Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

경쟁 프로그래밍을 위한 파이썬(Python) 빠른 입출력 방법 총정리

경쟁 프로그래밍에서 빠른 입출력이 중요한 이유

경쟁 프로그래밍(Competitive Programming)에서는 입력을 최대한 빠르게 읽어들이는 것이 다른 참가자보다 앞서는 핵심 요소입니다. 이 글에서는 파이썬(Python)으로 경쟁 프로그래밍을 할 때 활용할 수 있는 다양한 입출력(I/O) 방법을 하나씩 살펴봅니다.

예를 들어 Codeforces나 SPOJ 같은 온라인 저지 사이트에서 네 개의 숫자 a, b, c, d를 입력받아 곱을 출력하는 문제가 주어졌다고 가정해 봅시다. 이 문제를 해결하는 방법은 여러 가지가 있습니다.

기본적인 입력 방법

방법 1: 리스트 컴프리헨션 사용

a, b, c, d = [int(x) for x in input().split()]
print(a*b*c*d)

리스트 컴프리헨션(list comprehension)을 사용하면 한 줄로 입력된 값들을 손쉽게 정수형으로 변환할 수 있습니다.

방법 2: map 함수 사용

a, b, c, d = map(int, input().split())
print(a*b*c*d)

map 함수를 사용하면 코드가 더 간결해지고, 리스트 컴프리헨션보다 실행 속도도 약간 더 빠릅니다.

sys.stdin과 sys.stdout 활용하기

내장 input() 함수보다 훨씬 빠른 처리 속도가 필요하다면 sys 모듈의 stdin과 stdout을 사용하는 것이 좋습니다.

방법 3: stdin/stdout과 리스트 컴프리헨션 조합

from sys import stdin, stdout
a, b, c, d = [int(x) for x in stdin.readline().rstrip().split()]
stdout.write(str(a*b*c*d) + "\n")

stdin.readline()은 줄 끝의 개행 문자(\n)까지 함께 읽어오므로, rstrip()으로 제거한 후 split()을 적용하는 것이 일반적입니다.

실전 예제: SPOJ INTEST 문제

이번에는 실제 경쟁 프로그래밍 문제인 SPOJ의 INTEST - Enormous Input Test를 통해 입출력 방식에 따른 성능 차이를 직접 확인해 보겠습니다.

문제 설명

  • 입력: 첫 번째 줄에 두 개의 양의 정수 n과 k가 주어집니다(n, k ≤ 10⁷). 이후 n개의 줄에 걸쳐 10⁹ 이하의 양의 정수 tᵢ가 하나씩 주어집니다.
  • 출력: k로 나누어 떨어지는 정수 tᵢ의 개수를 출력합니다.

예제

Input
7 3
1
51
966369
7
9
999996
11

Output
4

위 예제에서 k=3으로 나누어 떨어지는 수는 51, 966369, 9, 999996으로 총 4개입니다.

방법 1: 기본 input() 함수 사용

def main():
    n, k = [int(c) for c in input().split()]
    cnt = 0
    for _ in range(n):
        t = int(input())
        if t % k == 0:
            cnt += 1
    print(cnt)

if __name__ == "__main__":
    main()

가장 직관적인 방법이지만, 입력량이 많을 때는 실행 시간이 오래 걸려 시간 초과(TLE)가 발생할 수 있습니다.

방법 2: stdin.readline() 사용

from sys import stdin, stdout

def main():
    n, k = [int(c) for c in input().split()]
    cnt = 0
    for _ in range(n):
        t = int(stdin.readline())
        if t % k == 0:
            cnt += 1
    stdout.write(str(cnt))

if __name__ == "__main__":
    main()

stdin.readline()을 사용하면 input()보다 훨씬 빠르게 입력을 처리할 수 있어 실행 시간이 크게 단축됩니다.

방법 3: readlines()로 전체 입력 한 번에 읽기

from sys import stdin, stdout

def main():
    n, k = stdin.readline().split()
    n = int(n)
    k = int(k)

    cnt = 0
    lines = stdin.readlines()
    for line in lines:
        if int(line) % k == 0:
            cnt += 1
    stdout.write(str(cnt))

if __name__ == "__main__":
    main()

readlines()를 사용하면 남은 입력 전체를 한 번에 리스트로 불러옵니다. 반복 호출에 따른 오버헤드가 사라지기 때문에 앞선 두 방법보다도 훨씬 빠른 성능을 보여줍니다.

정리 및 추가 팁

경쟁 프로그래밍에서 파이썬의 입출력 성능을 극대화하려면 다음 사항을 기억하세요.

  • input() → sys.stdin.readline(): readline으로 바꾸는 것만으로도 상당한 속도 향상을 얻을 수 있습니다.
  • readlines() 또는 sys.stdin.read(): 입력량이 매우 클 경우 전체를 한 번에 읽어 처리하는 것이 가장 빠릅니다.
  • print() → sys.stdout.write(): 출력이 많은 문제에서도 write를 사용하면 도움이 되며, 출력 횟수 자체를 줄이는 것도 효과적입니다.
  • rstrip() 습관 들이기: 운영체제에 따라 줄바꿈 문자가 \r\n일 수 있으므로 rstrip()으로 안전하게 제거하는 것이 좋습니다.

입력 데이터의 크기가 큰 문제일수록 입출력 방식의 선택이 결과를 좌우합니다. 위에서 소개한 방법들을 상황에 맞게 활용해 시간 초과를 피하고 좋은 성적을 거두시길 바랍니다.