반응형
문제
P(n)은 n을 십진수로 표시했을 때 0이 아닌 각 자리수의 곱으로 정의한다.
다음 값을 구하라.
P(1) + P(2) + P(3) + ... + P(999999)
우선 무식한 방법
#!/usr/bin/python
##########################################################
# ZiffernProdukte
# ---------------------------------------------------------
# <45fe9e97$0$11610$3b214f66@aconews.univie.ac.at>
# ---------------------------------------------------------
# Mit P(n) bezeichnen wir das Produkt aller Ziffern
# 1,2,3,4,5,6,7,8,9 in der Dezimaldarstellung der Zahl n
# (die Ziffer 0 wird also nicht mitmultipliziert).
#
# Bestimme den Wert der Summe
#
# P(1) + P(2) + P(3) + ... + P(999999)
##########################################################
def ziffprod(n):
ret = 1
while n > 0:
z = n % 10
if z != 0:
ret = ret * z
n = n // 10
return ret
# -- main --
sum = 0
S_prev = 0
for i in range(1, 1000000):
sum = sum + ziffprod(i)
if i in (9, 99, 999, 9999, 99999, 999999, 9999999, 99999999):
print(i, sum)
print(46 * ( S_prev + 1) - 1)
S_prev = sum
print(i, sum)
그리고, 조금 생각하여 만든 점화식을 만들어 봤다.
Sn을 P(1)부터 P(10^n - 1)까지의 합이라고 정의해보면, 즉
S1 = P(1) + ... + P(9)
S2 = P(1) + ... + P(99)
S3 = P(1) + ... + P(999)
S4 = P(1) + ... + P(9999)
S5 = P(1) + ... + P(99999)
S6 = P(1) + ... + P(999999)
S1은 쉽다.
S1 = 1 + 2 + 3 + ... + 8 + 9 = 45
S2는 좀 복잡해 보인다. 그러나, 쭉 풀어서 써 놓아보면 패턴이 보인다.
S2 =
1 + 2 + 3 + ... + 8 + 9 + // 1 ~ 9
1 + 1 x 1 + 1 x 2 + 1 x 3 + ... + 1 x 8 + 1 x 9 + // 10 ~ 19
2 + 2 x 1 + 2 x 2 + 2 x 3 + ... + 2 x 8 + 2 x 9 + // 20 ~ 29
3 + 3 x 1 + 3 x 2 + 3 x 3 + ... + 3 x 8 + 3 x 9 +
...
9 + 9 x 1 + 9 x 2 + 9 x 3 + ... + 9 x 8 + 9 x 9 // 90 ~ 99
= S1 + // 1 ~ 9
1 + 1 x S1 + // 10 ~ 19
2 + 2 x S1 + // 20 ~ 29
3 + 3 x S1 +
...
9 + 9 x S1 // 90 ~ 99
= S1 + S1 + S1 x S1
다음번 수열과의 관계식을 잡아내기에는 아직 좀 부족하므로, S3를 살펴본다.
S3 =
1 + 2 + 3 + ... + 98 + 99 + // 1 ~ 99
1 + 1 x 1 + 1 x 2 + 1 x 3 + ... + 1 x 98 + 1 x 99 + // 101 ~ 199
2 + 2 x 1 + 2 x 2 + 2 x 3 + ... + 2 x 98 + 2 x 99 + // 201 ~ 299
...
9 + 9 x 1 + 9 x 2 + 9 x 3 + ... + 9 x 98 + 9 x 99 + // 901 ~ 999
= S2 + S1 + S1 x S2
= S1 x S2 + S1 + S2
= (S1+1)(S2+1) - 1
이렇게 까지 해보면 점화식이 아래와 같을 거라고 확신이 든다.
Si = (S1 + 1)(S(i-1) + 1) - 1
그리고 코드.
#!/usr/bin/python
##########################################################
# ZiffernProdukte
# ---------------------------------------------------------
# <45fe9e97$0$11610$3b214f66@aconews.univie.ac.at>
# ---------------------------------------------------------
# Mit P(n) bezeichnen wir das Produkt aller Ziffern
# 1,2,3,4,5,6,7,8,9 in der Dezimaldarstellung der Zahl n
# (die Ziffer 0 wird also nicht mitmultipliziert).
#
# Bestimme den Wert der Summe # # P(1) + P(2) + P(3) + ... + P(999999)
##########################################################
# s1 = P(1) + ... + P(9)
s1 = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
# s[i] = P(1) + ... + P(10 -1)
s = []
for i in range(7):
s.append(-1) # initialize array with absurd value
s[0] = 0 # When i = 0, 10^i - 1 = 0, 0 is legitimate
s[1] = s1
for i in range(2, 7):
s[i] = (s[1] + 1) * (s[i - 1] + 1) - 1
print(s)
728x90
'프로그래밍 > 알고리즘' 카테고리의 다른 글
[EP0062] 같은 숫자로 이루어진 세제곱이 다섯개 (0) | 2023.01.03 |
---|---|
[Python] 분수의 순환소수, 순환마디 구하기 (0) | 2022.07.27 |
[EP 057] 2의 제곱근의 연분수 표현 (0) | 2022.06.08 |
Swift codewars 연습문제 gravity (0) | 2022.05.27 |
[EP 047] 소인수분해의 소수의 갯수가 4개 (0) | 2021.12.30 |