ps. 크리스마스 이브에도 공부하고 있네 오히려 좋아..

문제

[BaekJoon] 2231 분해합

분해합을 먼저 정의하자면 자연수 N과 N을 이루는 각 자리수의 합을 의미한다.

자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다.

ex) 245의 분해합은 245 + 2 + 4 + 5 = 256. 256이 된다. 그래서 245는 256의 생성자가 된다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 출력하면 된다.

Input

자연수 N (1 <= N <= 1,000,000)

Output

가장 작은 생성자. 생성자가 없는 경우 0 출력



풀이

가장 처음으로 떠오른 생각은 N을 str로 바꿔 index를 이용하면서 다시 int로 바꿔서 합을 계산하면 되지 않을까? 였다. 근데 너무 귀찮은 작업인 것 같고 되는지도 솔직히 잘 몰랐다.

for문으로 해보려니까 좀 복잡해서 그냥 // 을 이용해 각 자릿수를 일단 구해보기로 했다. 입력이 1,000,000 까지니까 백만 자리부터 일의 자리 까지 구하기..

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import sys
input = sys.stdin.readline

n = int(input())
Tag = False

for i in range(1, n+1):
    
    # 자리수 구하기
    i1 = i // 1000000  
    i2 = i // 100000 % 10
    i3 = i // 10000 % 10
    i4 = i // 1000 % 10
    i5 = i // 100 % 10
    i6 = i // 10 % 10
    i7 = i % 10 

    # 분해합
    sum = i + i1 + i2 + i3 + i4 + i5 + i6 + i7

    if sum == n:
        Tag = True
        print(i)
        break

if Tag == False:
    print(0)

저렇게 일일이 자릿수를 구해서 각 자릿수의 합과 자기 자신 숫자를 더해서 분해합을 구했다.

i가 1부터 n까지 커지므로 분해합과 입력값이 같을 때 break 해주면 가장 작은 생성자를 구할 수 있다.

처음에 Tag = False로 설정해놓고 분해합과 입력값이 같으면 Tag = True로 바꿔주고 print 하였다. 이는 생성자가 없을 때(print 되지 않고 for문이 끝났을 때) for문이 끝나고 0을 출력하기 위해서 설정하였다.

별다른 문제 없이 코드가 정답이었지만 문득.. 다른 사람들은 이렇게 풀지 않았을 것 같다는 생각이 들었다.

그래서 풀이를 검색해봤더니 이런..

1
2
3
for i in range(1, n+1):
    num = sum((map(int, str(i))))
    sum0 = i + num # 분해합

내가 처음에 생각했던 게 이렇게 간단한 코드였다. 역시..

(map(int, str(i))) 이 부분에서 숫자 istr(i)를 사용해 문자열로 변환한 다음 int로 문자열의 각 문자에 매핑하여 각 문자를 정수로 변환한다. 따라서 i의 각 자리를 생성하는 것이다.

그런 다음 sum()을 해주면 각 자릿수의 합num을 구하고, i와 더해주면 분해합을 구할 수 있다.

이제 이 분해합이 입력값과 같은지 비교하여 출력하면 끝..

str(num[i번째 자릿수])..? 뭐 이런 식으로 일일이 다 하려고 생각했었는데

풀이를 통해 하나 배워갈 수 있었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import sys
input = sys.stdin.readline

n = int(input())

for i in range(1, n+1):
    num = sum((map(int, str(i))))
    sum0 = i + num

    if sum0 == n:
        print(i)
        break
    if i == n:
        print(0)

Leave a comment