백준 단계별 - 반복문
<백준 2739번 - 구구단> https://www.acmicpc.net/problem/2739
○문제
N을 입력받은 뒤, 구구단 N단을 출력하는 프로그램을 작성하시오. 출력 형식에 맞춰서 출력하면 된다.
○입력
첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 9보다 작거나 같다.
○출력
출력형식과 같게 N*1부터 N*9까지 출력한다.
N = int(input())
for i in range(1, 10) :
print(N, "*", i, "=", N*i )
- 오류: N = input()
입력값을 받을 때는 숫자를 입력해도 문자열로 형태로 입력된다는 것을 놓쳤다.
~ 수정 : N = int(input())
<백준 10950번 - A+B-3> https://www.acmicpc.net/submit/10950/
○문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
○입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
○출력
각 테스트 케이스마다 A+B를 출력한다.
t = int(input())
for i in range(t) :
A, B = map(int,input().split())
print(A+B)
- 오류: print(A, B)
A와 B의 값을 더한 결과를 출력해야 하는데 A,B 구하는 것에 급급해서 출력을 제대로 못했다.
~ 수정 : print(A+B)
<백준 8939번 - 합> https://www.acmicpc.net/problem/8393
○문제
n이 주어졌을 때, 1부터 n까지 합을 구하는 프로그램을 작성하시오.
○입력
첫째 줄에 n (1 ≤ n ≤ 10,000)이 주어진다.
○출력
1부터 n까지 합을 출력한다.
n = int(input())
my_sum = n*(n+1)//2
print(my_sum)
- 오류: my_sum = n*(n+1)/2
고등학생 때부터 외우고 있던 식을 그대로 구현했더니 소수점 첫째 자리ex)6.0 까지 나와서 틀렸다고 나왔다.
따라서 몫만 출력하도록 코드 수정
~ 수정 : my_sum = n*(n+1)//2
num = int(input())
import sys
sys.setrecursionlimit(10**7)
def my_sum(n):
if n <= 1:
return 1
else :
return n + my_sum(n-1)
print(my_sum(num))
- 오류: 파이썬은 최대 재귀한도가 제한되어 있다. 이를 늘려주지 않으면 recursion error 발생
~ 수정 : 아래 코드 추가(재귀한도 늘려주기)
import sys
sys.setrecursionlimit(10**7)
n = int(input())
result = 0
for i in range(1, n+1) :
result = result + i
print(result)
<백준 25304번 - 영수증> https://www.acmicpc.net/problem/25304
○문제
준원이는 저번 주에 살면서 처음으로 코스트코를 가 봤다. 정말 멋졌다. 그런데, 몇 개 담지도 않았는데 수상하게 높은 금액이 나오는 것이다! 준원이는 영수증을 보면서 정확하게 계산된 것이 맞는지 확인해보려 한다.
영수증에 적힌,
- 구매한 각 물건의 가격과 개수
- 구매한 물건들의 총 금액
을 보고, 구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하는지 검사해보자.
○입력
첫째 줄에는 영수증에 적힌 총 금액 X가 주어진다.
둘째 줄에는 영수증에 적힌 구매한 물건의 종류의 수 N이 주어진다.
이후 N개의 줄에는 각 물건의 가격 와 개수 b가 공백을 사이에 두고 주어진다.
○출력
구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하면 Yes를 출력한다. 일치하지 않는다면 No를 출력한다.
x = int(input())
n = int(input())
price = 0
for i in range(n) :
a, b = map(int,input().split())
price += a*b
if price == x :
print('Yes')
else :
print('No')
- 오류1:
for i in range(n) :
a, b = map(int,input().split())
if a*b == x :
print('Yes')
가격과 물건의 개수를 그때그때 입력받은 후 이것을 다 더해야 총 금액이 나오는데, 그 부분이 누락됨.
~ 수정1 :
for i in range(n) :
a, b = map(int,input().split())
price += a*b
if price == x :
print('Yes')
- 오류2:
for i in range(n) :
a, b = map(int,input().split())
price += a*b
if price == x :
print('Yes')
변수 price의 초기설정을 하지 않고 바로 반복문 입력을 받도록 코드를 짬.
~ 수정2 :
price = 0
for i in range(n) :
a, b = map(int,input().split())
price += a*b
if price == x :
print('Yes')
<백준 15552번 -빠른 A+B> https://www.acmicpc.net/problem/15552
○문제
본격적으로 for문 문제를 풀기 전에 주의해야 할 점이 있다. 입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간초과가 날 수 있다는 점이다.
Python을 사용하고 있다면, input 대신 sys.stdin.readline을 사용할 수 있다. 단, 이때는 맨 끝의 개행문자까지 같이 입력받기 때문에 문자열을 저장하고 싶을 경우 .rstrip()을 추가로 해 주는 것이 좋다.
또한 입력과 출력 스트림은 별개이므로, 테스트케이스를 전부 입력받아서 저장한 뒤 전부 출력할 필요는 없다. 테스트케이스를 하나 받은 뒤 하나 출력해도 된다.
○입력
첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.
○출력
각 테스트케이스마다 A+B를 한 줄에 하나씩 순서대로 출력한다.
import sys
t = int(sys.stdin.readline())
for i in range(t) :
A, B = map(int,sys.stdin.readline().split())
print(A+B)
**sys.stdin.readline()을 사용하면 다량의 입력에 대해 input()보다 훨씬 빠르게 처리할 수 있다.
<백준 11021번 - A+B-7> https://www.acmicpc.net/problem/11021
○문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
○입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
○출력
각 테스트 케이스마다 "Case #x: "를 출력한 다음, A+B를 출력한다. 테스트 케이스 번호는 1부터 시작한다.
t = int(input())
import sys
for i in range(1, t+1):
A,B = map(int,sys.stdin.readline().split())
print("Case #%d: %d" %(i,A+B))
- 오류: print("Case #",i,":", A+B)
문자열 포맷을 사용하지 않았다.
~ 수정: print("Case #%d: %d" %(i,A+B))
<백준 11022번 - A+B-8> https://www.acmicpc.net/problem/11022
○문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
○입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
○출력
각 테스트 케이스마다 "Case #x: A + B = C" 형식으로 출력한다. x는 테스트 케이스 번호이고 1부터 시작하며, C는 A+B이다.
t = int(input())
import sys
for i in range(1, t+1):
A,B = map(int,sys.stdin.readline().split())
print("Case #%d: %d + %d = %d" %(i,A, B, A+B))
**바로 이전 문제와 거의 똑같은 문제. 어렵지 않게 해결할 수 있었다.
<백준 2438번 - 별 찍기1> https://www.acmicpc.net/problem/2438
○문제
첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제
○입력
첫째 줄에 N(1 ≤ N ≤ 100)이 주어진다.
○출력
첫째 줄부터 N번째 줄까지 차례대로 별을 출력한다.
n = int(input())
for i in range(1, n+1) :
print("*"*i)
- 오류1 : for i in range(n)
range 함수의 특징, n 미만임을 간과함.
~ 수정1 : for i in range(n+1)
- 오류2 : for i in range(n+1)
range 함수의 특징, 0부터 시작하기 때문에 첫줄이 공백이 나온다는 점을 간과함.
~ 수정2: for i in range(1, n+1)
<백준 2439번 - 별 찍기2> https://www.acmicpc.net/problem/2439
○문제
첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제 + 오른쪽 정렬
○입력
첫째 줄에 N(1 ≤ N ≤ 100)이 주어진다.
○출력
첫째 줄부터 N번째 줄까지 차례대로 별을 출력한다.
n = int(input())
for i in range(1, n+1) :
print(' '*(n-i)+'*'*i)
- 오류 : print(' '*n-i+'*'*i)
혼합계산에서 *가 -보다 먼저 계산되기 때문에 우선순위 정리가 필요하다.
~ 수정 : print(' '*(n-i)+'*'*i)
<백준 10871번 - X보다 작은 수> https://www.acmicpc.net/problem/10871
○문제
정수 N개로 이루어진 수열 A와 정수 X가 주어진다. 이때, A에서 X보다 작은 수를 모두 출력하는 프로그램을 작성하시오.
○입력
첫째 줄에 N과 X가 주어진다. (1 ≤ N, X ≤ 10,000)
둘째 줄에 수열 A를 이루는 정수 N개가 주어진다. 주어지는 정수는 모두 1보다 크거나 같고, 10,000보다 작거나 같은 정수이다.
○출력
X보다 작은 수를 입력받은 순서대로 공백으로 구분해 출력한다. X보다 작은 수는 적어도 하나 존재한다.
n, x = map(int,input().split())
num_list = list(map(int,input().split()))
result_list = []
for i in range(n):
if num_list[i] < x :
result_list.append(num_list[i])
for i in result_list :
print(i, end = " ")
- 오류1 :
for i in range(n):
num = int(input())
if num < x :
print(num, end = ' ')
num 입력을 한 줄에 모두 받아야 하는데, n줄 만큼 입력 받고 있다.
~ 수정1 :
for i in range(n):
num = map(int,input().split())
if num < x :
print(num, end = ' ')
- 오류2 :
for i in range(n):
num = map(int,input().split())
if num < x :
print(num, end = ' ')
num에 숫자 여러 개를 공백으로 구분하여 저장 - 하나하나 비교할 방법이 마땅치 않다.
list 형태로 입력 받은 후 index 사용하여 추출하고, append 함수를 사용해야겠다.
~ 수정2 :
result_list = []
for i in range(n):
num_list = list(map(int,input().split()))
if num_list[i] < x :
result_list.append(num_list[i])
- 오류3 :
result_list = []
for i in range(n):
num_list = list(map(int,input().split()))
if num_list[i] < x :
result_list.append(num_list[i])
for 문 안에서 num을 입력받으면 여러 차례 반복된다. 바깥으로 빼내야 한다.
~ 수정3 :
num_list = list(map(int,input().split()))
result_list = []
for i in range(n):
if num_list[i] < x :
result_list.append(num_list[i])
- 오류4 :
num_list = list(map(int,input().split()))
result_list = []
for i in range(n):
if num_list[i] < x :
result_list.append(num_list[i])
list에 저장된 값들을 공백으로 구분하여 숫자 형태로 추출해야 한다. 반복문 다시 한 번 사용.
~ 수정4 : 아래 코드 추가
for i in result_list :
print(i, end = " ")
**지금가지 코딩테스트 푼 것들 중 가장 많은 시행착오를 겪었다. 그 대신 자료를 입력 받는 형태에 대해 더 깊은 이해를 할 수 있었기에 아주 유익한 배움인 걸로.
<백준 10952번 - A+B - 5> https://www.acmicpc.net/problem/10952
○문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
○입력
입력은 여러 개의 테스트 케이스로 이루어져 있다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
입력의 마지막에는 0 두 개가 들어온다.
○출력
각 테스트 케이스마다 A+B를 출력한다.
import sys
while True :
a, b = map(int,sys.stdin.readline().split())
if a == 0 and b == 0:
break
print(a+b)
- 오류 :
print(a+b)
if a == 0 and b == 0:
break
a와 b가 0이면 바로 종료되어야 하는데, 0을 출력한 후 종료된다.
순서 수정 필요.
~ 수정 :
if a == 0 and b == 0:
break
print(a+b)
<백준 10951번 - A+B - 4> https://www.acmicpc.net/problem/10951
○문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
○입력
입력은 여러 개의 테스트 케이스로 이루어져 있다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
○출력
각 테스트 케이스마다 A+B를 출력한다.
import sys
while True:
try:
a, b = map(int, sys.stdin.readline().split(" "))
print(a+b)
except:
break
- 오류1 :
while True :
a, b = map(int,sys.stdin.readline().split())
print(a+b)
종료 조건에 대해 설정되어 있지 않다. 입력값이 없을 경우도 고려해야 한다. 예외 처리 필요.
~ 수정1 :
try :
while True :
a, b = map(int,sys.stdin.readline().split())
print(a+b)
except Exception as e :
print(e)
- 오류2 :
try :
while True :
a, b = map(int,sys.stdin.readline().split())
print(a+b)
except Exception as e :
print(e)
오류 원인을 출력할 것이 아니라, 무한루프 속에서 종료하는 조건을 만들어 줘야 함.
~ 수정2 :
while True:
try:
a, b = map(int, sys.stdin.readline().split(" "))
print(a+b)
except:
break
** try...exept... 구문에서 except는 거의 오류 원인 출력 정도로 다루었는데, 반복문 안에서 종료 조건으로도 사용할 수 있다는 건 새롭다.
<백준 1110번 - 더하기 사이클> https://www.acmicpc.net/problem/1110
○문제
0보다 크거나 같고, 99보다 작거나 같은 정수가 주어질 때 다음과 같은 연산을 할 수 있다. 먼저 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. 그 다음, 주어진 수의 가장 오른쪽 자리 수와 앞에서 구한 합의 가장 오른쪽 자리 수를 이어 붙이면 새로운 수를 만들 수 있다. 다음 예를 보자.
26부터 시작한다. 2+6 = 8이다. 새로운 수는 68이다. 6+8 = 14이다. 새로운 수는 84이다. 8+4 = 12이다. 새로운 수는 42이다. 4+2 = 6이다. 새로운 수는 26이다.
위의 예는 4번만에 원래 수로 돌아올 수 있다. 따라서 26의 사이클의 길이는 4이다.
N이 주어졌을 때, N의 사이클의 길이를 구하는 프로그램을 작성하시오.
○입력
첫째 줄에 N이 주어진다. N은 0보다 크거나 같고, 99보다 작거나 같은 정수이다.
○출력
첫째 줄에 N의 사이클 길이를 출력한다.
n = int(input())
num = n
cnt = 0
while True :
ten = n//10
one = n%10
plus_result = ten+one
new_num = plus_result%10 + one*10
cnt += 1
n = new_num
if new_num == num:
break
print(cnt)
- 오류1 : n을 new_num으로 교체하는 코드 누락. n이 계속 바뀌면서 진행되어야 하는데, n의 값이 달라지지 않으니 무한루프를 빠져나올 수 없어 시간 초과.
~ 수정1 : 아래 코드 추가
num = n #나중에 기존 숫자와 비교하는 작업이 필요하기 때문에 복사해두어야 함.(n값이 변하기 전에)
n = new_num
- 오류2 : new_num = plus_result + one*10
plus_result의 일의 자리와 더해야 한다는 점을 놓쳤다.
~ 수정2 : new_num = plus_result%10 + one*10