[C언어/C++] 백준 cin, cout 시간초과 해결법

백준 문제를 풀다보면 평범하게 cin, cout을 사용해 코드를 작성하면 시간초과로 오답이 뜰때가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
 
int A, B, n = 0;
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
 
    int a = 0;
 
    while (1) {
        cin >> n;
        if (1 <= n && n <= 1000000break;
    }
 
 
    for (int i = 1; i < (n + 1); i++) {
        while (1) {
            cin >> A >> B;
            if (1 <= A && A <= 1000 && 1 <= B && B <= 1000break;
        }
        cout << A + B << “\n”;
    }
 
    return 0;
}
cs

그럴땐 위의 코드처럼

1
2
ios::sync_with_stdio(false);
cin.tie(NULL);
cs

이 부분을 추가해주면 된다.

ios_base::sync_with_stdio 구문은 C의 stdio와 C++의 iostream을 동기화 시켜주는 역할을 하는데 이걸 비활성화시켜줌으로써 C++만의 독립적인 버퍼를 생성해줘 사용하는 버퍼의 수가 줄어들게된 덕에 실행속도가 빨라지게 된다.

하지만 동기화 됬을 때의 C++ 버퍼는 thread-safe 하기 때문에 모든 입출력의 순서가 예상한 것과 정확히 일치함을 보장할 수 있는 것에 반해 동기화가 비활성화되게 되면 멀티 쓰레드 환경에서는 출력 순서를 보장할 수 없게된다.

그리고 stdio 라이브러리와 버퍼가 분리되었기 때문에 C++의 cin, cout 과 C의 scanf, gets, getchar, printf, puts, putchar 등을 함께 사용하면 안된다.

cin.tie(NULL); 코드는 cin과 cout의 묶음을 풀어주는 코드이다.

기본적으로 cin과 cout은 묶여있고 묶여있는 스트림들은 한 스트림이 다른 스트림에서 각 입출력 작업을 진행하기 전에 자동으로 버퍼를 비워줌을 보장하는데 이걸 묶음을 풀어줌으로써 버퍼를 비워주는 작업을 하지않게 되고 입출력이 그만큼 더 빨라지게 된다.

하지만 입출력의 순서를 보장받을 수 없다는 단점이 존재한다.

1
2
3
cout << A + B << endl;
 
cout << A + B << “\n”;
cs

endl 대신 ‘\n’을 사용하는 것도 입출력 속도 향상에 도움이된다.

endl에도 버퍼를 비워주는 기능이 있는데 그냥 ‘\n’을 사용해서 줄바꿈을 해주면 마찬가지로 버퍼를 비워주는 작업을 하지않게되기 때문에 입출력이 더 빨라질 수 있다.

관련글

제목 작성자 작성일