코딩 테스트/백준
[Python] 백준 2231 분해합
위시리
2024. 12. 29. 16:23
문제 분석
- 분해합이 주어졌을 때 가장 작은 생성자를 구하라
- 생성자가 없다면 0 출력
코드 설계
- 입력 받은 분해합을 최대한 분해
- 분해합이 3자리라고 할 때 가장 큰 분해합 - 생성자 = 27 (9+9+9)
정답 코드
실패.. 아이디어가 안떠오른다..
다른 사람 코드 1
n = int(input())
for i in range(1, n + 1):
num = sum((map(int, str(i)))) # i의 각 자릿수를 더함
num_sum = i + num # 분해합 = 생성자 + 각 자릿수의 합
# i가 작은 수부터 차례로 들어가므로 처음으로 분해합과 입력값이 같을 때 가장 작은 생성자를 가짐
if num_sum == n:
print(i)
break
if i == n: # 생성자 i와 입력값이 같다는 것은 생성자가 없다는 의미
print(0)
다른 사람 코드 2
n = int(input())
result = 0
for i in range(1, n+1):
nums = list(map(int, str(i)))
result = sum(nums) + i
if result == n:
print(i)
break
if i == n:
print(0)
- bruteforce
- 입력과 빈 변수를 만들고
- 분해합에 해당하는 숫자를 찾기 위해 1부터 입력값 까지의 모든 수를 더해서 찾는다.
- 브루트 포스를 위한 for문을 작성한 뒤 i 값을 각 자릿수로 슬라이싱하여 리스트로 만드는 함수 검색
- result에 sum(nums)와 i를 선언하여 i라는 수와 i의 각 자릿수의 합을 더한다.
- i가 분해합을 찾지 못하고 n까지 가게 된다면 분해합이 없는 경우 → 0 출력
다른 사람 코드 3 - 2에서 좀 더 간단하게
https://afterdawncoding.tistory.com/60
N = int(input())
x = 0
for i in range(N):
a = list(map(int, str(i)))
if N == sum(a) + i:
x = i
break;
print(x)
** 해설
1. 1부터 입력한 값 N까지를 증가시키는 반복문을 돌리면서 각 숫자에 대한 분해합을 구한다.
정수의 각 자릿수를 리스트로 받기 위해서는 map()함수를 활용해야 한다.
문자열은 iterable에 해당하므로 1~입력받은 값(정수로 변환한) N까지의 값에 해당하는 i를 str으로 형변환하여 받고, 다시 map()함수로 각 자릿수 값을 int로 형변환한다.
이렇게하면 N에 245를 입력받았을 때 리스트 a에 [2, 4, 5]를 담을 수 있다.
N = int(input())
x = 0
for i in range(N):
a = list(map(int, str(i)))
if N == sum(a) + i:
x = i
break;
print(x)
2. 구한 분해합이 입력한 숫자와 같다면 해당 분해합 값은 입력한 숫자의 생성자이므로 반복문을 빠져나와 그 값을 출력한다.
sum함수는 리스트의 모든 원소를 더한 값을 반환한다. 여기에 i를 더하면 i의 분해합이 된다.
이 값이 입력한 값 N과 같다면 N의 생성자와 같은 값이므로 반복문을 탈출하여 그 값을 출력하도록 한다.
GPT 설명
for i in range(N):
a = list(map(int, str(i)))
1. for i in range(N)
- range(N):
- 숫자 0부터 N-1까지의 정수 시퀀스를 생성합니다.
- 예: N = 5일 경우 range(5)는 [0, 1, 2, 3, 4]와 같은 시퀀스를 만듭니다.
- for i in range(N):
- range(N)에서 생성된 숫자 하나하나를 i에 할당하면서 반복합니다.
- 예: N = 5일 경우, i의 값은 순서대로 0, 1, 2, 3, 4가 됩니다.
2. str(i)
- 숫자 i를 문자열로 변환합니다.
- str() 함수는 숫자나 다른 자료형을 문자열로 바꾸는 역할을 합니다.
i = 123
str(i) # 출력: "123" (문자열)
- 변환 이유:
- 숫자의 각 자릿수를 개별적으로 처리하려면, 문자열로 변환해야 합니다.
3. map(int, str(i))
- str(i):
- 숫자 i를 문자열로 변환한 값입니다.
- 예: i = 123일 경우, str(i)는 "123"입니다.
- map(int, str(i)):
- str(i)는 문자열 "123"처럼 문자로 이루어진 시퀀스입니다.
- map()은 각 문자에 대해 int 함수를 적용하여, 문자열을 다시 정수로 변환합니다.
i = 123
list(map(int, str(i))) # 출력: [1, 2, 3]
동작 과정:
- str(i)가 반환한 문자열 "123"은 "1", "2", "3"이라는 개별 문자로 분리됩니다.
- map(int, ...)는 각 문자에 대해 int를 적용하여 정수로 변환합니다.
- "1" → 1
- "2" → 2
- "3" → 3
- 결과는 [1, 2, 3]처럼 정수 리스트로 변환됩니다.
4. list(map(int, str(i)))
- map(int, str(i))는 이터레이터 형태로 반환되므로, 이를 리스트로 변환하여 사용할 수 있게 합니다.
- 결과:
- i = 123일 경우:
python코드 복사list(map(int, str(i))) # 출력: [1, 2, 3]
- i = 123일 경우:
동작 흐름 전체
for i in range(N): # 0부터 N-1까지 반복
a = list(map(int, str(i))) # i를 자릿수 별로 쪼개고 정수 리스트로 변환
예제: N = 5
- i = 0 → str(0) = "0" → list(map(int, str(0))) = [0]
- i = 1 → str(1) = "1" → list(map(int, str(1))) = [1]
- i = 2 → str(2) = "2" → list(map(int, str(2))) = [2]
- i = 3 → str(3) = "3" → list(map(int, str(3))) = [3]
- i = 4 → str(4) = "4" → list(map(int, str(4))) = [4]
요약
- str(i): 숫자 i를 문자열로 변환.
- map(int, str(i)): 문자열을 구성하는 각 문자를 정수로 변환.
- list(map(int, str(i))): 변환된 결과를 리스트로 반환.
이 부분은 숫자를 자릿수 단위로 분해하여 정수 리스트로 변환하는 작업입니다
2회차 - 25.02.18
문제 분석
- 어떤 자연수 N
- 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미
- M ( 생성자 ) - N ( 분해합 )
코드 설계
- 입력(n)을 받고, 1~n 반복하면서(i) 만약 현재 i와 i의 각 자리수의 합이 n과 같으면 break
- 끝까지 탐색했는데 없다면 0 출력
정답 코드
import sys
input = sys.stdin.readline
n = int(input())
for i in range(1, n+1) :
num = list(str(i)) # 각 자리수 추출 -> 문자열 -> list
# 각 자리가 str인 list의 값을 int로 바꿔서 합을 구하려고 한다.
num_sum = sum(map(int, num))
if n == (i+num_sum) :
print(i)
exit(0)
print(0)