Python/백준 예제 풀이 모음

[백준] [Python] 15552번: 빠른 A+B

Dailybook406 2022. 10. 23. 21:41

[ 문제 ]

본격적으로 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 등 일부에서는 이 기능이 실행되지 않는다고 한다.

(참고: https://www.acmicpc.net/board/view/38043)

 

#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