[백준] [Python] 15552번: 빠른 A+B
[ 문제 ]
본격적으로 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()을 추가로 해 주는 것이 좋다.
또한 입력과 출력 스트림은 별개이므로, 테스트케이스를 전부 입력받아서 저장한 뒤 전부 출력할 필요는 없다. 테스트케이스를 하나 받은 뒤 하나 출력해도 된다.
자세한 설명 및 다른 언어의 경우는 이 글에 설명되어 있다.
이 블로그 글에서 BOJ의 기타 여러 가지 팁을 볼 수 있다.
[ 조건 ]
<입력>
첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.
<출력>
각 테스트케이스마다 A+B를 한 줄에 하나씩 순서대로 출력한다.
[ 풀이 ]
# My solution
import sys #1
input = sys.stdin.readline #2
T = int(input()) #3
for _ in range(T) : #4
A, B = map(int,input().split())
print(A+B)
실행결과
5 # T입력
1 1 # 입력1
2 # 출력1
12 34 # 입력2
46 # 출력2
5 500 # 입력3
505 # 출력3
40 60 # 입력4
100 # 출력4
1000 1000 # 입력5
2000 # 출력5
문제에서 이야기했듯이 한 두 줄 정도의 짧은 입력이 아니라, 여러 줄을 입력받거나 출력할 때 입출력 방식이 느리면 시간초과 문제가 발생할 수 있다.
문제에서는 T의 경우는 단순히 한 번만 입력받기 때문에 input()을 사용해도 무관하다.
하지만 반복문을 통해 여러 줄을 입력받고 출력하려면 `sys.stdin.readline()`을 사용해야만 시간초과가 발생하지 않는다.
sys 모듈은 파이썬 인터프리터가 제공하는 변수와 함수를 직접 제어할 수 있게 해주는 모듈이다.
sys 모듈의 기능 중 하나인 `sys.stdin.readline()`은 쉽게 생각하면 input()과 같은 기능을 하는 함수이다.
괄호 안에 입력받은 값을 문자형(str)으로 저장한다.
하지만 input()과 다른 sys.stdin.readline()의 특징으로는 입력을 받은 값의 끝에 개행문자(줄바꿈문자, \n)를 함께 입력받는다는 점이다.
예를 들어 `a = sys.stdin.readline(10)`을 입력하면 실제 a에는 '10\n'이 입력된다.
import sys
a = sys.stdin.readline()
print(f'o{a}o')
실행결과
10 # 입력값
o10
o # 출력값
a에 입력된 값을 알아보기 위해서 a의 앞 뒤에 임의로 'o'를 붙여서 출력한 결과 줄바꿈이 되어있음을 확인할 수 있다.
그렇기 때문에 문자열을 온전히 입력받고 싶은 경우 문제에서 알려주었듯이 오른쪽의 공백을 제거해주는 `. rstrip()`을 통해 개행문자를 없애주어야 한다.
그렇다면 왜 두 함수 input()과 sys.stdin.readline() 사이 속도 차이가 발생하는 것일까?
우선 input()의 경우 sys.stdin.readline()에서의 개행문자를 삭제시켜서 입력을 받는다.
또한 input()의 괄호 안에 매개변수로 문자열을 입력받는 경우 아래 예시와 같이 프롬프트에 입력한 문자열을 출력하지만, sys.stdin.readline()에는 이러한 기능이 없다.
a = input('나이를 입력해주세요!')
>>> 나이를 입력해주세요!
얼핏 보면 굉장히 사소한 차이일 수 있지만, 반복적으로 많은 값을 입력받는 경우 이 사소한 차이로 인하여 시간 차이가 발생한다.
문제에서 참고하라고 알려준 사이트에서처럼 입력을 받을 때마다 `sys.stdin.readline`을 입력하기에는 너무 길기 때문에 평소 우리가 사용하던 input을 변수로 생성하여 사용하면 편할 것이다.
import sys
input = sys.stdin.readline
a = int(input())
print(a)
참고로 주피터 노트북이나 colab 등 일부에서는 이 기능이 실행되지 않는다고 한다.
#1
sys 모듈을 사용하기 위해서 import를 한다.
#2
sys.stdin.readline을 편하게 사용하기 위해서 평소 사용하는 input을 변수로 만들어 대입한다(위의 '+sys 모듈과 sys.stdin.readline' 참고).
#3
반복을 할 테스트케이스 T를 입력받는다.
#4
for 반복문을 사용하여 T만큼 반복을 한다.
이때 for의 변수로 _(언더바)를 사용하면 변수를 사용하지 않고 반복을 한다.
map()함수를 통해 A와 B를 동시에 입력받고 print()로 A+B를 출력한다.
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