

위의 문제의 경우 테스트 케이스의 개수가 1,000,000개로 매우 많은 반면,
시간 제한은 1초이다.
이런 경우, 일반적인 <iostream>의 cin,cout 을 활용한 방법으로
입,출력을 하게되면 시간 초과 에러가 발생한다.
그렇다면 어떤 방식으로 입,출력을 해야 시간 초과 에러를 피할 수 있을까?
크게 2가지 방법이 있다.
<stdio.h\>나<cstdio>의scanf(),printf()를 활용하면 입,출력이 매우 빠르게 수행되어 시간 초과를 막을 수 있다.
C++ 스타일로
<iostream\>을 사용하더라도cin.tie(NULL)와ios_base::sync_with_stdio(false)를 코드에 넣어주면
입,출력 시간 초과 에러를 막을 수 있다.
ios_base::sync_with_stdio(false) 가 필요한 배경은 무엇일까?
C++은 기본적으로 C style 의 코드와 동시에 사용할 수 있도록 설계되어있다.
입, 출력의 경우도 마찬가지이다.
C++의 cin/cout은 원래 버퍼를 갖고 동작하는데, 기본값으로 C style인
stdio 의 scanf, printf와 섞어 써도 입,출력 순서가 꼬이지 않도록
내부적으로 매번 동기화 로직이 수행된다.
이는 입,출력 과정에서 지연 을 유발하고 -> 시간 초과 에러로 이어진다.
이때 ios_base::sync_with_stdio(false) 를 수행하면 <iostream>이
<stdio>와 버퍼를 동기화하는 작업을 수행하지 않게되어 입,출력 속도가 향상된다.
(그러나 ios_base::sync_with_stdio(false) 를 사용하는 순간 C style 입출력과
C++ style 입출력의 혼용이 불가해지고 , 둘 중 하나만 사용해야한다)
cin.tie(NULL)은cin과cout의묶음(tie)을 끊는 것이다.
이를 이해하기 위해선 입력과 출력의 유기적인 동작을 이해해야한다.
결론부터 말하자면,
cin과 cout은 기본적으로 tie되어 있어서, cin으로 입력하기 전에 cout을 flush해 입력문 실행전에 출력 데이터가 콘솔에서 보이게한다.
기본적으로 cin과 cout은 연결되어 동작한다.
cout << "값 입력: ";
cin >> x;
위의 코드의 cout << ... 를 살펴보면 flush를 유발하기위한 "\n"도 없고 endl 도 없다.
이런 경우 사용자가 "값 입력: " 이라는 문자가 콘솔에 뜨지않으니 입력해야할
타이밍을 알 수 없게된다.
이를 방지하기위해 C++은 입력을 받기전에 기본값으로 출력 버퍼를 Flush 하도록 설계되어있다.
(이것이 cin과 cout이 tie 되어있음을 의미한다)
그러나 Flush는 내부적으로 연산에 많은 시간이 소요되기에
입,출력을 번갈아 수행하는경우 Flush가 계속 일어나 지연이 발생한다.
이를 막기위해 cin.tie(NULL)을 수행해주면 cin과 cout 사이의 연결이
끊기고 endl 과 같은 flush를 유발하는 코드가 있을때만 flush 하게되어
입출력 속도가 향상된다.
#include <cstdio>
int main() {
int T, a, b;
scanf("%d", &T);
for (int i=0; i<T; i++) {
scanf("%d %d", &a, &b);
printf("%d\n", a+b);
}
return 0;
}
#include <iostream>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T,a,b;
cin >> T;
for (int i=0; i<T; i++) {
cin >> a >> b;
cout << a + b << "\n";
}
return 0;
}

신기한게, C++ style 입출력에 빠른 입출력을 적용하기 전까지는
항상 C style 입출력이 빨랐는데 빠른 입출력 적용 이후에는 C++ Style이 더욱 빠르다.
WOW