빠르게 입력받고 출력하는 문제
본격적으로 for문 문제를 풀기 전에 주의해야 할 점이 있다. 입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간초과가 날 수 있다는 점이다.
C언어의 표준 입출력인 scanf()와 printf()를 쓰는 방법이다.
C++와 표준 스트림의 동기화 해제
ios_base::sync_with_stdio(false);
기본적으로 C++에서는 C++와 C의 표준 스트림이 동기화 되어있음. C++에서 C와 C++ 각각의 스타일로 입출력을 받아도 서로 동기화하여 우리가 입력 혹은 출력하고자 하는 순서대로 결과를 얻을 수 있음. 즉, C와 C++가 동일한 버퍼를 공유함.
이러한 동기화는 성능을 저하시키는 원인이 되지만, 두 스트림의 동기화는 우리가 입출력에 있어 C와 C++의 IO(Input-Output)을 혼용하여 쓸 때 매우 합리적이고 스레드로부터 안전하기 때문에 원래는 동기화 상태로 두는 것이 올바름.
예를들면 입력의 경우 std::cin은 stdin과 동기화 되며, std::cout은 stdout과 동기화가 됨.
다만, 알고리즘 문제 풀이에서는 예외 처리나 멀티스레드 작업을 필요로 하지 않기 때문에 두 동기화를 끊어주어도 무방.
그럼 동기화를 끊는다는 것은? C 스트림과 C++ 스트림이 서로 동기화 되어있는데 이 동기화를 끊는 다는 것은 C++ 표준 스트림이 독립적으로 IO 버퍼링을 할 수 있다는 것. 그렇게 되면 상당히 많은 양의 입출력이 있을 경우 동기화 되어있는 상태에 비해 성능이 많이 좋아짐.
즉, 이러한 작업을 위해 ios_base에 있는 sync_with_stdio() 을 활용하여 위 코드처럼 적용시키면 동기화가 해제 됨. 직역해보면 stdio와의 싱크(동기화) 메소드인 것. 여기에 파라미터로 false을 해주면 동기화가 해제.
그리고 중요한 점은 동기화를 해제했기 때문에 C와 C++ 스타일 중 하나를 선택해서 써야 함. 혼용하여 쓰면 안됨.
입력과 출력 연결 끊어주기
cin.tie(NULL); // 또는 cin.tie(nullptr), cin.tie(0) 으로 대체 가능
기본적으로 입력과 출력은 연결되어있음.
기본적으로 입력 요청이 들어오면 그 전에 출력 작업이 있었을 경우(출력 버퍼에 내용이 있는 경우) 버퍼를 비워(flush) 출력을 하게 됨.
즉, 입력 요청을 통해 읽어들이게 될 경우 이 전에 있던 출력 작업들을 콘솔창에 보이도록 버퍼를 비움.
sol2)
#include <iostream>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> T;
int a, b;
for (int i = 0; i < T; i++) {
cin >> a >> b;
cout << a + b << "\n";
}
}
sol1)
#include <stdio.h>
using namespace std;
int main() {
int T;
scanf("%d", &T);
int a, b;
for (int i = 0; i < T; i++) {
scanf("%d %d", &a, &b);
printf("%d\n", a + b);
}
}