파이썬(PYTHON)/코딩테스트

백준 단계별 - 반복문

Hana_h 2022. 8. 28. 15:30

<백준 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