PS/BOJ

[BOJ] 인터랙티브 문제를 풀어보자.

kth990303 2021. 12. 26. 13:46
반응형

인터랙티브 문제는 어떻게 푸는걸까?

물론 백준 대부분에선 인터랙티브 문제를 어떻게 풀어야 하는지 하단에 힌트를 통해 친절하게 알려주는 편이긴 하다.

언어별 표준 출력버퍼 flush 방법 (출처: 23306번 문제 노트)

이번엔 https://www.acmicpc.net/problem/18649 문제와 https://www.acmicpc.net/problem/23306 문제 풀이를 보면서 인터랙티브를 어떻게 푸는지 살펴보려 한다.

 

참고로 인터랙티브 태그에 '함수구현' 문제도 좀 있는 편인데,

이건 프로그래머스 스타일을 한번이라도 봤으면 쉽게 접근할 수 있고,

인터랙티브와 함수구현은 엄연히 다르다고 생각해 '함수구현'문제는 여기서 풀지 않을 것이다.


23306. binary는 호남선

https://www.acmicpc.net/problem/23306

 

23306번: binary는 호남선

입출력이 어떤 방식으로 이루어지는지 이해를 돕기 위해, 의도적으로 제한 조건과 줄 간격 등을 조절한 것이다. 실제 입출력 및 제한 조건과 다른 것에 유의하자. 주어진 binary는 호남선의 철로

www.acmicpc.net

풀이는 굉장히 간단하다.

a[1], a[N]의 값을 물어본 후, 오르막이면 1, 내리막이면 -1, 평평하면 0을 출력해주면 된다.

 

a[1]을 a, a[N]을 b라 하자.

우리가 묻고 싶은 값은 a[1], a[N]이므로 표준 출력(stdout) cout을 통해 ? 1, ? N과 같이 물어봐주자.

인터랙티브에선 cout 출력의 역할이 채점기에게 질문을 하는 것과 같다.

 

물어볼 때는 표준 입력(stdin)을 받으라 했으므로 cin을 통해 입력받자.

인터랙티브에선 cin 입력의 역할이 채점기에게 답변을 받는 것과 같다.

 

#include <bits/stdc++.h>
using namespace std;
int N,a,b;
int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> N;
	cout << "? 1"<<endl;
	cin >> a;
	cout << "? " << N <<endl;
	cin >> b;
	if (a == 1 && b == 0)
		cout << "! -1"<<endl;
	else if (a == 0 && b == 1)
		cout << "! 1"<<endl;
	else
		cout << "! 0"<<endl;
}

참고로 endl은 "\n"와 같은 역할을 하나, 여기에 추가로 버퍼까지 비워주는 flush역할까지 한다.

 

즉, 개행문자 역할에 flush역할을 함께 해주기 때문에 "\n"보다는 시간이 더 걸려 백준에선 자주 쓰지 않으나,

인터랙티브 문제에선 어차피 flush로 시간이 소요되므로 \n + flush로 코드를 두 줄 쓸바에 endl을 쓰는게 낫다고 생각한다.

잘못된 방법으로 버퍼를 플러시하거나 타이밍에 맞지 않게 플러시하면 시간초과나 틀렸습니다를 받으므로 주의하자.


18649. Lowest Unique

https://www.acmicpc.net/problem/18649

 

18649번: Lowest Unique

First, your program needs to read three integers $n$, $k$ and $m$ ($3 \le n \le 10$, $\frac{n}{2} < k < n$, $m$ is either 2 or 1000, and $m$ is 1000 in all cases except the sample case. Then you need to repeat the following process $m$ times: you need to p

www.acmicpc.net

예전에 풀어서 문제가 잘 기억이 안나는데다가,

영어 해석이 귀찮아서 풀이는 따로 언급하지 않겠다.

 

대신 주의할 점은, 반드시 cout을 먼저 해준 후에 cin을 받아주어야 하며,

그 전에 endl 또는 flush로 버퍼를 비워줘야 한다.

cin을 먼저하고 cout을 나중에 하면 시간초과를 받는다.

인터랙티브 문제는 문제에서 하라는 타이밍대로 버퍼를 비워주어야 시간초과 또는 틀렸습니다를 받지 않는다는 것에 주의하자.

웬만해선 cout이나 cin을 한줄에 다 하고 나면 그때그때 flush해준다고 생각하면 될 듯하다.

#include <bits/stdc++.h>
using namespace std;
int n,k,m;
int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin>>n>>k>>m;
	while(m--){
		int num;
		for(int i=1;i<=k;i++)cout<<i<<" ";
		cout<<endl;
		for(int i=0;i<n-k;i++)cin>>num;
	}
}

인터랙티브 문제.

사용법을 알면 재밌고, 모르면 수많은 맞왜틀로 개빡침을 선사하는 문제.

 

이참에 사용법을 제대로 익히도록 하자 ㅎㅎ

반응형