- 论坛徽章:
- 0
|
这个问题很早以前在Python的列表里讨论过,用排列组合非常快就可以出来了。我去找找,把程序也给贴上来。前面用公式证明的那个,可能就是用的排列组合。
def f(n):
"""f(n) = Sum{g(k)}, k=1..n
where g(k) = number of '1's in decimal presentation of k
"""
m = 1; r = 0
# In the i-th loop, we sum No. of '1' showed in the i-th position
# (start from the RIGHT) of all k's decimal presentation, k=1..n.
# m == 10**(i-1), i.e. the order of i-th digit.
while m <= n:
head = n / (m *10) * (m * 10) # digits to the left of digit_i
digit_i = n / m % 10 # the i-th digit
tail = n % m # digits to the right of digit_i
# Example: for n=23456 and m=100, head=23000,digit_i=4,tail=56
# This many '1's showed on the i-th position of k, for k=1..head-1.
r += head / 10
if digit_i == 1:
r += tail + 1 # No. of '1's showed on i-th position for
k=head..n
elif digit_i > 1:
r += m # same as above, but diff. calculation
# Select the (i+1)-th position.
m *= 10
return r
#import pdb
#pdb.set_trace()
#look for some n2 satisfying f(n2) >= n2
n = 1; loops = 0
while n < 10**100:
loops += 1
F = f(n)
if F == n:
print "f(" + str(n) + ") = " + str(F) + ", loop " + str(loops)
n += 1
elif F < n:
# find the order of n
m = 10; d = 1 # m = 10**d holds
while m <= n:
m *= 10; d += 1
# now d == No. of digits in str(n)
# this jump will never be "too long", since there is no more than
# n-F '1's between n+1 and n+jump. (f(n+jump) equals n+jump only
when
# each number between n+1 and n+jump has d '1's
jump = (n - F) / d
if jump > 0:
n += jump
else:
n += 1
else: # F > n
# this is equivalent to new_n = n+(F-n),
# and f(new_n) == f(n+(F-n)) >= f(n) == F == n+(F-n) == new_n
n = F
#print "not satisfied: f(" + str(n) + ") = " + str(F) |
|