학습 정리/👨‍💻 PS Study

[C++] 백준 15552번 - 빠른 A+B

무딘붓 2023. 1. 4. 10:39

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

 

15552번: 빠른 A+B

첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.

www.acmicpc.net

[소스코드]

int main(void) {
	int a, b, t;

	cin.tie(NULL);
	ios::sync_with_stdio(false);

	cin >> t;
	for (int i = 0; i < t; i++) {
		cin >> a >> b;
		cout << a + b << "\n";
	}

	return 0;
}

C++의 cin과 cout의 느린 속도를 확인하기에 좋은 문제이다.

 

C언어의 printf, scanf는 충분히 빠르기 때문에 그냥 사용하면 쉽게 풀리지만,

C++의 cin, cout은 상대적으로 느리기 때문에 그냥 사용하면 시간 초과가 된다.

 

cin.tie(NULL);
ios::sync_with_stdio(false);

cin과 cout을 빠르게 사용하기 위해선 위의 코드 2줄이 필요하다.

 

우선, cin.tie(NULL);cin과 cout의 묶음을 풀어 준다.

이게 무슨 소리냐 하면, cin과 cout의 입력과 출력은 원래 묶여있는데 이것을 풀어서 속도를 높이는 것이다.

구체적으로 말하면 cin으로 입력이 들어오면 출력 버퍼에 내용이 있는 경우 버퍼를 비워(flush) 출력한다. 따라서, 입출력이 반복되는 경우 매번 일일이 버퍼를 비우느라 시간이 더 걸린다.

 

ios::sync_with_stdio(false);C의 stdio와 C++의 iostream의 동기화를 비활성화 한다.

C의 stdio와 C++의 iostream은 기본적으로 동기화 되어있으므로, C++에서 C 스타일로 입출력을 받아도 원하는 입출력 결과를 받을 수 있다. 예를 들어, cin과 scanf, gets, getchar를 함께 사용할 수 있는 것이다.

하지만, cin과 cout만 사용하는 경우 동기화는 불필요하기 때문에, 이를 비활성화 시켜서 속도를 향상시킬 수 있는 것이다. 따라서, 비활성화 후에는 cin과 scanf, gets, getchar 그리고 cout과 printf, puts, putchar를 같이 사용하면 안 된다.

 

 

위의 코드를 적용하여 실제 입출력 시간을 얼마나 줄일수 있는지 아래 문제를 이용하여 확인해 보았다.

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

 

2751번: 수 정렬하기 2

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

 

cin, cout 속도 개선 비교

위의 제출이 cin.tie(NULL);과 ios::sync_with_stdio(false); 두줄의 코드를 추가한 코드이고,

아래 제출이 코드 추가 없이 cin과 cout을 사용한 결과이다.

 

cin.tie(NULL);과 ios::sync_with_stdio(false);를 사용한 결과가 약 2~3배 더 빠른 속도를 보여준다.

 

다른 언어에 대한 설명은 아래 링크 참고

https://www.acmicpc.net/board/view/22716