백준 2231번 "분해합"

Question:

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

Input:

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

Output:

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

Example Case:

Input: 216

Output: 198

풀이 과정: 이 문제는 방정식을 이용하여 풀이 방향을 이끌어 나가려고 한 문제이다. 예를 들어, 자연수 245의 분해합이 256인데, 이는, 256 = 245 + 2 + 4 + 5을 의미한다. 이를 방정식으로 나타내본다면, x + y + z + 100x + 10y + z = N 의 값을 구하는 것이다.

따라서, 처음엔 N의 값을 입력받은 후, N과 K의 관계를 이용하여 코드를 작성하였다.

예를 들자면, N = K(원래 세자리수) + (K-K%100)/ 100 (백의 자리) + K%100-K&10(십의 자리) + K%10(일의 자리) 으로 작성하였는데, 이는 문제 파악이 제대로 되지 않아서, N의 값의 범위를 그만 놓치고 코드를 작성해버렸다. 이는 N이 세자리수 한정일때나 성립되는 식이며,해당 사용중이던 언어 C++도 익숙하지 않아 문제풀이에 막혔다. 결국 python 언어를 통해 문제 풀이에 접근하였다. str 함수를 사용하여,한자리수 숫자를 각각 분리하여 저장한뒤, 분해합의 정의를 이용하여 답을 도출해 내었다.

1
2
3
4
5
6
7
8
9
10
11
12
N = int(input()) # N에 대한 입력

result = 0 #N과 비교하기위한 변수

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)

Conclusion 문제를 파악할 때 더 깊이 생각해보자.. 변수의 범위에 유의하자.