Algorythm/백준 BEAKJOON

[BAEKJOON/ 백준] 2231번: 분해합

gapsoo 2024. 5. 8. 14:58

https://www.acmicpc.net/problem/2231

 


[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)

 

 

  • n = int(input()): 사용자로부터 분해합을 입력값으로 받는다.
  • for i in range(1, n+1):: 1부터 입력값까지의 모든 수에 대해 반복한다. 이 범위 안에서 각 숫자에 대해 생성자를 찾는다.
  • num = sum((map(int, str(i)))): 현재 숫자 i의 각 자릿수를 더하여 분해합을 구한다. str(i)를 사용하여 숫자를 문자열로 변환하고, map(int, str(i))를 사용하여 문자열의 각 문자를 숫자로 변환한 뒤, sum() 함수를 사용하여 자릿수의 합을 구한다.

✔️ 두 번 변환하는 이유?

 

두 번 변환하는 이유는 주어진 숫자를 각 자릿수로 분리하여 각 자릿수의 합을 구하기 위함이다.

처음에 숫자를 문자열로 변환하는 이유는, 문자열로 변환하면 숫자를 각 자릿수로 분리하기 쉬워지기 때문이다. 예를 들어, 숫자 123은 문자열 "123"으로 변환되며, 이를 순회하면 각각의 자릿수인 '1', '2', '3'에 접근할 수 있다.

두 번째로 문자열의 각 문자를 다시 정수로 변환하는 이유는, 문자열로 변환된 각 자릿수를 숫자로 처리하기 위해서이다. 문자열로 처리된 각 자릿수는 사실상 문자로 인식되므로, 숫자로 사용하기 위해서는 정수형으로 변환해야 한다.

따라서, 처음에 숫자를 문자열로 변환하고, 이후에 문자열의 각 문자를 다시 정수로 변환하여 각 자릿수의 합을 계산하는 과정이 필요하다.

 

 

  • num_sum = i + num: 분해합은 생성자인 i와 각 자릿수의 합인 num을 더한 값이다.
  • if num_sum == n:: 분해합과 입력값이 같을 때, 즉 분해합의 생성자를 찾은 경우이다.
  • print(i): 가장 작은 생성자를 출력한다,
  • break: 생성자를 찾았으므로 더 이상 반복할 필요가 없으므로 반복문을 종료한다.
  • if i == n:: 생성자를 찾지 못한 경우, 즉 모든 수를 확인했지만 분해합의 생성자가 없는 경우이다.
  • print(0): 생성자가 없다는 의미로 0을 출력한다.

 

 

✔️ 예시: 216

사용자로부터 입력값으로 분해합을 받는다. 이 예시에서는 216을 입력값으로 받는다.

for i in range(1, n+1):를 통해 1부터 입력값까지의 모든 수에 대해 반복한다. 따라서 이 코드에서는 1부터 216까지의 수에 대해 반복하게 된다.

반복문 내부에서는 각 숫자 i에 대해 다음을 수행합니다:
num = sum((map(int, str(i)))): 현재 숫자 i의 각 자릿수를 더하여 분해합을 구한다. 즉, 각 자릿수를 문자열로 변환하고 이를 정수로 매핑한 뒤, 이를 모두 합하여 자릿수의 합을 구한다. 216의 각 자릿수의 합은 2 + 1 + 6 = 9가 된다.

num_sum = i + num: 분해합은 생성자인 i와 각 자릿수의 합인 num을 더한 값이다.
if num_sum == n:을 통해 분해합과 입력값이 같은지 확인한다. 즉, 현재 숫자 i가 생성자일 때이다.

num_sum이 216과 같은지 확인한다.

만약 같다면, 이 숫자 i가 입력값에 대한 가장 작은 생성자이다. 따라서 이 값을 출력하고 반복문을 종료한다.

if i == n:을 통해 생성자를 찾지 못한 경우, 즉 모든 수를 확인했지만 분해합의 생성자가 없는 경우를 처리한다.

 

 

 


[2] 느낀 점

 

코드 길이는 짧지만 이 알고리즘을 떠올리는 건 어려운 것 같다...🥲

여러 문제를 접해보면서 새로운 아이디어를 자꾸 떠올리게 되어서 조금 고통스러웠지만 좋았다!