Software Hyena::

[백준 15688번] - 수 정렬하기 5 / C++ (sync_with_stdio, cin.tie, cout.tie) 본문

알고리즘/백준

[백준 15688번] - 수 정렬하기 5 / C++ (sync_with_stdio, cin.tie, cout.tie)

bluehyena 2021. 2. 20. 20:38
반응형

www.acmicpc.net/problem/15688

 

15688번: 수 정렬하기 5

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이며, 같은 수가 여러 번 중복될 수도 있다.

www.acmicpc.net

문제 <시간누적>

N개의 수가 주어졌을 때, 이를 비내림차순으로 정렬하는 프로그램을 작성하시오.

길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.

입력

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이며, 같은 수가 여러 번 중복될 수도 있다.

출력

첫째 줄부터 N개의 줄에 비내림차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.

 

--------------------------------------------------------------------------------------------------------

풀이

이번 문제는 그냥 Algorithm의 sort를 쓰면 되는 문제이다. 그런데 왜 굳이 포스팅을 했을까?

그 이유는 시간누적 문제이기 때문이다. 처음의 시간 초과가 난 코드를 우선 살펴보자. 

 

<C++>

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> v;

int main() {
	int N;
	cin >> N;

	int number;

	for (int i = 0; i < N; ++i) {
		cin >> number;
		v.push_back(number);
	}

	sort(v.begin(), v.end());

	for (int i = 0; i < N; ++i) {
		cout << v[i] << '\n';
	}

	return 0;
}

이렇게 코드를 제출 했더니 시간 초과가 났다. 하지만, 단순히 코드 3줄만 추가했더니 시간초과가 사라지고 정답처리가 되었다. 아래 코드를 살펴보자.

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> v;

int main() {
	// 추가한 코드
	ios::sync_with_stdio(false);
	cout.tie(NULL);
	cin.tie(NULL);

	int N;
	cin >> N;

	int number;

	for (int i = 0; i < N; ++i) {
		cin >> number;
		v.push_back(number);
	}

	sort(v.begin(), v.end());

	for (int i = 0; i < N; ++i) {
		cout << v[i] << '\n';
	}

	return 0;
}

단순히 저 세 줄의 코드만 추가하였더니 정답처리가 되었다. 그렇다면 저 코드들의 역할은 무엇일까?

 

1. ios::sync_with_stdio(false)

C언어의 표준 stream과 C++ 의 표준 stream의 동기화를 끊는 코드이다. 이렇게 동기화를 끊게 되면 사용하는 버퍼의 수가 줄어들어 실행속도가 향상된다. 단, 이 경우에는 C언어에서 사용하는 printf나 scanf등의 함수는 혼용해서 사용하면 안된다.

 

2. cout.tie(NULL), cin.tie(NULL)

cin과 cout은 stream 버퍼를 공유한다. 이를 tie 한다고 표현하며 tie가 되어있는 경우 입출력 요청을 받게 되면 실행전에 stream의 버퍼를 확인하고 flush를 한다. 하지만, cout.tie(NULL), cin.tie(NULL)로 untie를 하면, 이런 과정을 거치지 않고 바로 입출력을 한다.

 

 

PS를 할때 입출력 속도를 위해 많이 사용되는 코드들이라고 한다. 여담으로 endl 보다 '\n' 을 통해 개행을 하는 것이 속도면에서 훨씬 빠르니 이런 팁들은 잘 기억해두도록 하자.

반응형
Comments