문제
어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.
자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.
입력
첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.
출력
첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.
코드
n = int(input())
i = 1
min = n-9*len(str(n))
for i in range(min, n+1):
sum = i+(i//1000000 % 10)+(i//100000 % 10)+(i//10000 % 10) + \
(i//1000 % 10)+(i//100 % 10)+(i//10 % 10)+(i % 10)
if n == sum:
print(i)
break
if n == i:
print(0)
break
풀이
1부터 수를 증가시키며 n까지 대입해보는 방법은, 시간초과로 실패!
경우의 수를 줄이기 위해 반복문의 최소값에 무엇이 들어갈지 생각해봐야 한다.
간단하게 생성자 111의 경우 분해합은 111+1+1+1이 되고, 999의 경우 999+9+9+9가 된다.
따라서 반복문의 최소값은 n-9*(자릿수)가 된다.
풀이2 - 문자열 사용
n = int(input())
result = 0
for i in range(1, n+1):
a = list(map(int, str(i)))
result = i+sum(a)
if result == n:
print(i)
break
if i == n:
print(0)
다른 분들의 풀이를 참고했다.
간단하게 n을 문자열로 바꾸고, 문자열은 배열처럼 자릿수를 반환할 수 있으니..
list(map(int, str(n))를 사용하면 자릿수로 형성된 리스트를 얻을 수 있다.
예를 들어 n=198일 때 list는 ['1', '9', '8']이 된다.
이 리스트를 map 함수를 이용해 각각 int형으로 변환해주고, 동일하게 n+n의 각 자릿수 덧셈을 수행해주면 된다.
다만, 이 방법은 시간이 1.5s정도로 오래 걸렸다. 문자열을 처리하는 게 시간이 더 오래걸리는 것 같다.
위에서처럼 동일하게 반복문의 min 값을 지정해주려고 했는데, 답이 자꾸 틀렸다.
반례를 좀 더 찾아봐야겠다.
'👩🏻💻 Front-end > 👾 Algorithm' 카테고리의 다른 글
백준 1436 - 영화감독 숌 (Python) (0) | 2022.05.17 |
---|---|
파이썬 7568 - 덩치 (Python) (0) | 2022.05.17 |
백준 2798 - 블랙잭 (Python) (0) | 2022.05.15 |
백준 17478 - 재귀함수가 뭔가요? (Python) (0) | 2022.05.15 |
백준 10870 - 피보나치 수 5 (Python) (0) | 2022.05.14 |