RiseOJ는 solved.ac와 제휴 관계가 없습니다. 티어 아이콘 © solved.ac. solved.ac
← 브론즈 II

빠른 입출력

sync_with_stdio(false)·sys.stdin — 입출력 병목 제거.

기초 & 구현 Bronze II 브론즈 II
선수 지식: 입력출력
1강 빠른 입출력: 시간 초과(TLE)를 막는 법 공식

왜 빠른 입출력이 필요한가?

입출력하는 줄 수가 수십만 ~ 수백만 줄이 되면, 입출력 자체가 느려서
시간 초과(TLE)가 나기도 합니다. 알고리즘이 맞아도 입출력 때문에 떨어지는
것이죠. 다행히 정해진 몇 줄만 추가하면 크게 빨라집니다.


1. C++ — 동기화 끄기 3종 세트

main맨 처음에 넣으세요.

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    // 이후 cin / cout 사용
}
  • sync_with_stdio(false) — C 표준 입출력(scanf/printf)과의 동기화를 끊어 cin/cout을 빠르게 만듭니다.
  • cin.tie(nullptr) — 입력 전마다 출력을 자동으로 비우던 동작을 꺼서 속도를 올립니다.

주의: 동기화를 끈 뒤에는 cin/coutscanf/printf섞어 쓰지 마세요.


2. C++ — 출력은 '\n', endl 금지

cout << x << '\n'; // 빠름 (권장)
cout << x << endl; // 느림 — 매번 버퍼를 비운다(flush)

출력이 많을 때 endl'\n'으로 바꾸기만 해도 눈에 띄게 빨라집니다.


3. Python — input() 대신 sys.stdin

파이썬 기본 input()은 줄 수가 많으면 느립니다.

import sys
input = sys.stdin.readline # 한 줄을 빠르게 읽는다

n = int(input())
for _ in range(n):
    a, b = map(int, input().split())
    # ...

sys.stdin.readline줄바꿈 문자(\n)까지 함께 읽으므로, 문자열을
비교할 땐 .rstrip()으로 끝의 줄바꿈을 떼 주세요. (숫자로 int(...) 변환할
땐 줄바꿈이 자동으로 무시되어 괜찮습니다.)


4. Python — 출력도 모아서 한 번에

print를 수십만 번 부르면 느립니다. 결과를 모았다가 한 번에 출력하세요.

import sys
out = []
for i in range(n):
    out.append(str(i * i))
sys.stdout.write('\n'.join(out) + '\n')

또는 print('\n'.join(map(str, answers))) 처럼 한 줄로도 가능합니다.


5. 자주 하는 실수

  • endl 남발 — 출력이 많은 문제에서 가장 흔한 TLE 원인.
  • 동기화 끄고 scanf와 혼용 — 입력 순서가 꼬일 수 있습니다.
  • readline의 줄바꿈 — 문자열 비교 시 \n이 붙어 있어 틀리는 경우. .rstrip() 하세요.

연습 팁

입출력 양이 많아 보이는 문제(예: "최대 1,000,000개의 수")를 만나면, 코드를
짜기 전에
위의 빠른 입출력 틀부터 깔아 두세요. 나중에 TLE가 났을 때
원인을 찾느라 헤매는 시간을 아낄 수 있습니다.

2강 입출력 병목을 더 깊이 이해하기 공식

왜 입출력이 병목이 되는가

알고리즘은 맞는데 시간 초과가 난다면, 진짜 원인이 입출력일 수 있습니다. 입력
데이터가 수십만 줄을 넘어가면 "읽고 쓰는 행위 자체"가 무거워집니다. 그 이유와
해결책을 한 단계 깊이 봅니다.


1. 무엇이 느린가

  • C++ cin/cout 은 기본적으로 C의 scanf/printf동기화되어 있어 느립니다.
  • endl 은 줄바꿈마다 출력 버퍼를 강제로 비워(flush) 매우 느립니다.
  • 파이썬 input() 은 호출마다 부가 처리를 해서 대량 입력에 느립니다.

핵심은 "한 줄 한 줄 처리할 때 생기는 자잘한 비용"이 수십만 번 쌓인다는 것입니다.


2. C++ 빠른 입출력 (정석)

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false);  // C 입출력과 동기화 해제
    cin.tie(nullptr);                  // cin 전 cout 자동 flush 해제

    int n; cin >> n;
    // ... cout << ... << '\n';        // endl 대신 '\n'
}

세 줄이 한 세트입니다.

  1. sync_with_stdio(false) — C++/C 입출력 버퍼 분리(빨라짐).
  2. cin.tie(nullptr) — 입력 전 출력 자동 비우기 끄기.
  3. '\n' 사용 — endl의 강제 flush 피하기.

주의: sync_with_stdio(false) 이후엔 cin/coutscanf/printf섞어 쓰지
마세요.


3. 파이썬 빠른 입출력 (정석)

import sys
input = sys.stdin.readline      # 빠른 입력으로 교체

n = int(input())
out = []
for _ in range(n):
    a, b = map(int, input().split())
    out.append(str(a + b))
print('\n'.join(out))           # 한 번에 출력
  • sys.stdin.readlineinput보다 빠르게 한 줄 읽기.
  • 출력은 리스트에 모았다가 '\n'.join으로 한 번에print를 수십만 번 부르는
    것보다 훨씬 빠릅니다.

4. 언제 꼭 써야 하나

입력 규모 빠른 입출력
수천 줄 이하 없어도 무방
\(10^5\) 줄 이상 권장
\(10^6\) 줄 이상 거의 필수

문제 제약에서 \(N \le 1{,}000{,}000\) 같은 큰 수가 보이면 반사적으로 켜세요.


정리

  • 느림의 원인: 동기화, endl의 flush, input() 부가 비용.
  • C++: sync_with_stdio(false) + cin.tie(nullptr) + '\n'.
  • 파이썬: sys.stdin.readline + 출력 모아서 한 번에.
  • 입력이 \(10^5\)를 넘으면 켜는 습관.
3강 빠른 입출력 실전 적용과 함정 공식

빠른 입출력 실전 템플릿과 주의점

실제 문제에서 빠른 입출력을 어떻게 끼워 넣는지, 그리고 자주 터지는 함정을
코드로 정리합니다.


1. C++ 전체 템플릿

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n; cin >> n;
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        sum += x;
    }
    cout << sum << '\n';
    return 0;
}

대량 출력이 있다면 '\n'을 쓰는 것만으로도 큰 차이가 납니다.


2. 파이썬 전체 템플릿

import sys
input = sys.stdin.readline

def main():
    n = int(input())
    out = []
    for _ in range(n):
        x = int(input())
        out.append(str(x * 2))
    sys.stdout.write('\n'.join(out) + '\n')

main()

main() 함수로 감싸면 파이썬에서 약간 더 빠르고 구조가 깔끔합니다.


3. 한 번에 다 읽기 (초대량)

입력이 정말 많으면 통째로 읽어 쪼개는 방법이 가장 빠릅니다.

import sys
data = sys.stdin.read().split()   # 모든 토큰을 한 번에
idx = 0
n = int(data[idx]); idx += 1
nums = [int(data[idx + i]) for i in range(n)]
// C++도 sync 해제 + cin >> 면 충분히 빠르므로 보통 위 템플릿이면 OK

4. 함정과 패턴 인식

  • readline 줄바꿈sys.stdin.readline()은 끝에 \n이 붙습니다. 문자열을
    비교할 땐 .rstrip()으로 떼어 주세요(숫자 변환 시엔 int()가 알아서 무시).
  • endl 남용 — 반복 출력에서 endl을 쓰면 그대로 시간 초과. '\n'으로 교체.
  • sync 후 섞어 쓰기sync_with_stdio(false)scanf/printf 혼용 금지.
  • print 수십만 번 — 파이썬에서 루프마다 print는 느림. 모아서 한 번에.

문제에서 "\(N \le 10^6\)", "수가 매우 많다", "시간 제한이 빡빡" 같은 신호가
보이면 빠른 입출력을 먼저 적용하세요.


정리

실전에서는 (1) C++ 세 줄 세트 + '\n', (2) 파이썬 sys.stdin.readline + 출력
모으기, (3) 초대량이면 sys.stdin.read().split() — 이 세 가지 템플릿을 통째로
외워 두면 입출력 때문에 시간 초과 나는 일이 사라집니다.