파이썬 알고리즘 : 숫자의 표현

규칙성 찾기

2023년 12월 18일 알고리즘 문제풀이

문제

숫자의 표현

난이도

Lv.2

코드

1
2
3
4
5
6
7
8
9
10
def solution(n):
    answer = 1
    if n == 1 or n == 2:
        return answer
    tmp = 3
    while tmp <= n:
        if not n%tmp:
            answer += 1
        tmp += 2
    return answer

처음엔 DP로 생각했다. 생각하다보니, DP 라면 이전 것들이 계속 더해지는 형태라는 의미인데, 결국 숫자가 너무 커질 것이라는 생각이 들었다. 따라서 DP를 이용하는 문제라면 어떤 수로 나눈 나머지를 기록하도록 문제가 나왔을거라고 생각이 들어서 DP가 아닌 규칙성을 찾기로 하였다. 홀수의 경우 절반으로 나눈 몫과 그 몫의 1을 더한 경우가 항상 존재한다. 예를 들어, 15일 때 절반으로 나눈 몫은 7임. 1은 더한 값 8과 함께 7+8=15 로 표현될 수 있다. 이 규칙은 모든 홀수에게 적용되지만, 모든 짝수에게는 적용될 수 없다. 연속된 두 개의 수는 하나는 홀수고 하나는 짝수기 때문에 결과가 홀수로만 나타나기 때문이다. 그래서 홀수 일 떄만 생각하면 된다고 판단하였다. 짝수일 떄는 0일 것이라고 생각했지만, 연속된 수는 1개만 있어도 되기 떄문에, 어떤 자연수든 자기 자신 1개로만 표현될 수 있다고 생각하여 짝수일 때는 항상 1을 반환하게 만들었다. 그 외의 홀수는 홀수로 나누면 된다고 생각했다. 예시에서 15는 4가지 경우가 있다. 15, 7+8, 4+5+6, 1+2+3+4+5 이 중 앞에 15와 7+8은 예외적인 경우로 따져서 규칙성에서 배제하였다. 1개로 나타내는 수는 앞서 말했듯 누구에게나 적용되는 규칙이고, 7+8은 홀수라면 무조건 적용되는 규칙이기 때문이다. 즉 4+5+6과 1+2+3+4+5 가 15가 가지는 규칙인데, 총 더해지는 숫자의 갯수가 홀수개라고 생각했다. 가운데 수를 기준으로 양쪽에 하나씩, 두개씩, 세개씩 붙는 규칙이라고 파악했다. (2n+1)로 나누었을떄 나누어 떨어지면 된다. 15는 3,5로 나누어떨어지니 저 2개가 규칙이 생긴 것이다. 같은 논리로, 17과 19는 그 다음 홀수인 7로 나누어 떨어지지 않기 떄문에 15와 같은 갯수를 가질 것이다. 반면 21은 7로 나누어 떨어지기 떄문에 한 가지 경우가 추가될 것이고, 그 이후 9로 나누어 떨어지는 수가 나타나면 또 추가될 것이다. 여기서 일부 예외가 발생하였는데, 짝수를 배제한 것이 잘못되었다. 예를 들어 1+2+3은 6이다. 내가 세운 가설에 의하면 6은 연속된 수를 6 자기 자신을 제외하곤 없지만, 막상 실제로는 존재한다. 따라서 짝수 홀수와 상관없이 (2n+1)로만 나누어지면 내가 만든 규칙에 적용될 수 있다고 생각하여 짝수, 홀수를 따지지 않았더니 해결되었다.