백준 단계별로 풀어보기에서 문제를 풀던 중 15552번 : 빠른 A+B 문제 내용에 생소한 것이 쓰여져 있어 알아보았다.
https://www.acmicpc.net/problem/15552
본격적으로 for문 문제를 풀기 전에 주의해야 할 점이 있다. 입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간초과가 날 수 있다는 점이다.
C++을 사용하고 있고 cin/cout을 사용하고자 한다면, cin.tie(NULL)과 sync_with_stdio(false)를 둘 다 적용해 주고, endl 대신 개행문자(\n)를 쓰자. 단, 이렇게 하면 더 이상 scanf/printf/puts/getchar/putchar 등 C의 입출력 방식을 사용하면 안 된다.
Java를 사용하고 있다면, Scanner와 System.out.println 대신 BufferedReader와 BufferedWriter를 사용할 수 있다. BufferedWriter.flush는 맨 마지막에 한 번만 하면 된다.
Python을 사용하고 있다면, input 대신 sys.stdin.readline을 사용할 수 있다. 단, 이때는 맨 끝의 개행문자까지 같이 입력받기 때문에 문자열을 저장하고 싶을 경우 .rstrip()을 추가로 해 주는 것이 좋다.
또한 입력과 출력 스트림은 별개이므로, 테스트케이스를 전부 입력받아서 저장한 뒤 전부 출력할 필요는 없다. 테스트케이스를 하나 받은 뒤 하나 출력해도 된다.
지문에 써있는 cin.tie(NULL) 과 ios_base::sync_with_stdio(false) 를 쓰면 시간초과가 나지 않고 해결된다고 하는데
추후 다른 문제를 풀 때에도 도움이 될 것 같아 조금 알아보았다.
ios_base::sync_with_stdio(false)
코드의 의미는 C 의 stdio 와 C++ 의 iostream 의 동기화를 비활성화 한다는 뜻이다.
원래는 활성화가 되어 있어 C 스타일과 C++ 스타일을 혼용해도 문제가 없지만 (cin / cout, scanf / printf) 등을 한 코드에 작성하는 경우)
stdio 와 iostream 을 동기화하는 과정에서 딜레이가 발생함으로
동기화를 비활성화하고 독립 버퍼를 사용하게끔 하여 성능을 높이기 위해 사용한다.
stdio 와 iostream 의 동기화를 비활성화하였기 때문에 C++ 의 cin / cout 과 C 의 scanf / printf, gets / puts, getchar / putchar 을 혼용해서 사용하면 안된다.
cin.tie(NULL)
코드의 의미는 cin 과 cout 의 묶음을 풀어준다 라는 뜻이다.
cout << "너의 이름은?";
cin >> name;
원래는 cin 과 cout 이 묶여있어 무조건 출력이 되고 입력을 받아 매번 출력 버퍼를 비워주는 작업 (flush) 이 실행되는데
묶음을 풀어주게 되면 순서가 보장되지 않고 실행되다보면 나중에 한 번에 출력이 처리가 될 수 있기 때문에 딜레이가 감소하는 효과를 얻을 수 있다.
알고리즘 문제를 풀 때에는 입출력의 순서가 그리 중요하지 않아
입출력이 여러 번 번갈아가면서 있다면 묶음을 풀어주어 딜레이를 감소시키기 위해 사용한다고 한다.
endl
C++ 로 문제를 풀 때 개행을 하기 위해 보통
cout << "hello" << endl;
endl 구문을 사용하는데
endl 은 개행과 동시에 출력 버퍼를 비워주는 작업까지 하여 딜레이가 발생한다고 한다.
cout << "hello" << "\n";
이스케이프 문자로 개행을 해주면 된다.