[λ°±μ€€/python] 4673번 : μ…€ν”„ λ„˜λ²„

2021. 3. 9. 16:30

문제

μ…€ν”„ λ„˜λ²„λŠ” 1949λ…„ 인도 μˆ˜ν•™μž D.R. Kaprekarκ°€ 이름 λΆ™μ˜€λ‹€. μ–‘μ˜ μ •μˆ˜ n에 λŒ€ν•΄μ„œ d(n)을 nκ³Ό n의 각 자리수λ₯Ό λ”ν•˜λŠ” ν•¨μˆ˜λΌκ³  μ •μ˜ν•˜μž. 예λ₯Ό λ“€μ–΄, d(75) = 75+7+5 = 87이닀.

μ–‘μ˜ μ •μˆ˜ n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 이 수λ₯Ό μ‹œμž‘ν•΄μ„œ n, d(n), d(d(n)), d(d(d(n))), ...κ³Ό 같은 λ¬΄ν•œ μˆ˜μ—΄μ„ λ§Œλ“€ 수 μžˆλ‹€. 

예λ₯Ό λ“€μ–΄, 33으둜 μ‹œμž‘ν•œλ‹€λ©΄ λ‹€μŒ μˆ˜λŠ” 33 + 3 + 3 = 39이고, κ·Έ λ‹€μŒ μˆ˜λŠ” 39 + 3 + 9 = 51, λ‹€μŒ μˆ˜λŠ” 51 + 5 + 1 = 57이닀. μ΄λŸ°μ‹μœΌλ‘œ λ‹€μŒκ³Ό 같은 μˆ˜μ—΄μ„ λ§Œλ“€ 수 μžˆλ‹€.

33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...

n을 d(n)의 μƒμ„±μžλΌκ³  ν•œλ‹€. μœ„μ˜ μˆ˜μ—΄μ—μ„œ 33은 39의 μƒμ„±μžμ΄κ³ , 39λŠ” 51의 μƒμ„±μž, 51은 57의 μƒμ„±μžμ΄λ‹€. μƒμ„±μžκ°€ ν•œ κ°œλ³΄λ‹€ λ§Žμ€ κ²½μš°λ„ μžˆλ‹€. 예λ₯Ό λ“€μ–΄, 101은 μƒμ„±μžκ°€ 2개(91κ³Ό 100) μžˆλ‹€. 

μƒμ„±μžκ°€ μ—†λŠ” 숫자λ₯Ό μ…€ν”„ λ„˜λ²„λΌκ³  ν•œλ‹€. 100보닀 μž‘μ€ μ…€ν”„ λ„˜λ²„λŠ” 총 13κ°œκ°€ μžˆλ‹€. 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97

10000보닀 μž‘κ±°λ‚˜ 같은 μ…€ν”„ λ„˜λ²„λ₯Ό ν•œ 쀄에 ν•˜λ‚˜μ”© 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

μž…λ ₯

μž…λ ₯은 μ—†λ‹€.

 

좜λ ₯

10,000보닀 μž‘κ±°λ‚˜ 같은 μ…€ν”„ λ„˜λ²„λ₯Ό ν•œ 쀄에 ν•˜λ‚˜μ”© μ¦κ°€ν•˜λŠ” μˆœμ„œλ‘œ 좜λ ₯ν•œλ‹€.

 

μ •λ‹΅

N = 10000
selfie = [False for i in range(N+1)]


def digit_hap(num):
    s = num
    while num > 0:
        s += num % 10
        num = num//10
    return s


for i in range(1, N+1):
    if selfie[i] == False:
        move = i
        while True:
            if move < 10:
                move = 2*move
            else:
                move = digit_hap(move)
            if move > N:
                break
            selfie[move] = True

for idx, value in enumerate(selfie):
    if value == False and idx != 0:
        print(idx)

μ²˜μŒμ—λŠ” μƒμ„±μžκ°€ μžˆλŠ” 숫자λ₯Ό μ œμ™Έν•œ 수λ₯Ό 좜λ ₯ν•΄μ•Όν•œλ‹€λŠ” κ±° μžμ²΄κ°€ λ„ˆλ¬΄ λ§‰λ§‰ν–ˆλ‹€.

κ²°κ΅­ 10,000κΉŒμ§€μ˜ λͺ¨λ“  숫자λ₯Ό κ²€μƒ‰ν•΄μ•Όν–ˆλ‹€. 

selfie = [False for i in range(N+1)]

λ°°μ—΄μ˜ indexλ₯Ό ν™œμš©ν•˜κΈ° μœ„ν•΄ μ›ν•˜λŠ” λ²”μœ„(N) + 1 κΉŒμ§€μ˜ 배열을 λ§Œλ“€μ–΄ λͺ¨λ“  값에 Falseλ₯Ό μ €μž₯ν•œλ‹€.

def digit_hap(num):
    s = num
    while num > 0:
        s += num % 10
        num = num//10
    return s

num의 λͺ¨λ“  자릿수λ₯Ό λ”ν•˜κΈ° μœ„ν•΄ digit_hap ν•¨μˆ˜λ₯Ό λ§Œλ“ λ‹€.

μš°μ„  10으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό λ”ν•œ ν›„ num을 10으둜 λ‚˜λˆˆ λͺ«μ„ μ΄μš©ν•˜μ—¬ 맨 끝의 μžλ¦¬λΆ€ν„° μž˜λΌλ‚΄λ©° λ°˜λ³΅ν•œλ‹€.

for i in range(1, N+1):
    if selfie[i] == False:
        move = i
        while True:
            if move < 10:
                move = 2*move
            else:
                move = digit_hap(move)
            if move > N:
                break
            selfie[move] = True

selfieκ°€ False인 값에 ν•œν•˜μ—¬ digit_hap ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€.

μ΄λ•Œ ν•œμžλ¦¬μΈ μˆ˜λŠ” digit_hap을 μ‚¬μš©ν•  ν•„μš”μ—†μ΄ ν•΄λ‹Ή 숫자λ₯Ό *2ν•΄μ£Όλ©΄ λœλ‹€.

μ‹€ν–‰ν•œ κ²°κ³Όκ°€ μ›ν•˜λŠ” λ²”μœ„μΈ N보닀 크닀면 배열에 μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— breakλ₯Ό μ΄μš©ν•˜μ—¬ λ°˜λ³΅λ¬Έμ„ λΉ μ Έλ‚˜κ°€κ³ 

그렇지 μ•Šλ‹€λ©΄ ν•΄λ‹Ή index의 값을 True둜 λ°”κΎΈμ–΄μ€€λ‹€.

for idx, value in enumerate(selfie):
    if value == False and idx != 0:
        print(idx)

enumerateλ₯Ό μ΄μš©ν•˜μ—¬ μΈλ±μŠ€μ™€ ν•΄λ‹Ή 값을 μ΄μš©ν•˜μ—¬ 값이 False인 κ²ƒλ§Œ 좜λ ₯ν•œλ‹€.

728x90

BELATED ARTICLES

more