17、有这样一个函数,对于任意整数n,都能返回写出0到n之间出现“1”的个数。例如,f(13)=6。请注意f(1)=1,那么下一个能实现f(n)=n的最大数字是什么?
以下为验证代码:
Option Explicit
Private Sub Command1_Click()
Dim i As Long
Dim s As Double
Dim s2 As Double
Dim s1 As Double
Dim s3 As Double
s = 0
s1 = 1
s2 = 1
s3 = 1
For i = 1 To 20
s = s + s2 * 2 + s3 * 10 + 1
Debug.Print i, s2, s
s2 = s3 * 10 + s2 * 10
s3 = s3 * 10
Next
End Sub
程序输出结果:
1 1 13
2 20 154
3 300 1755
4 4000 19756
5 50000 219757
6 600000 2419758
7 7000000 26419759
8 80000000 286419760
9 900000000 3086419761
10 10000000000 33086419762
11 110000000000 353086419763
12 1200000000000 3753086419764
13 13000000000000 39753086419765
14 140000000000000 419753086419766
15 1.5E+15 4.41975308641977E+15
16 1.6E+16 4.64197530864198E+16
17 1.7E+17 4.8641975308642E+17
18 1.8E+18 5.08641975308642E+18
19 1.9E+19 5.30864197530864E+19
20 2E+20 5.53086419753086E+20
可以看出那个数在1000000000-2222222221之间(10位数)
'1-26补充完整
Private Function f(ByVal n As Long)
Static num1(9) As Long '定义 num1(1)=f(1)+..+f(9),num1(2)=f(1)+...+f(99)
Dim i As Long, j As Long
Dim s As Long
Dim s1 As Long
Dim s2 As Long
Dim s3 As Long
Dim m As Long
Dim mmod As Long
'预处理
If num1(1) = 0 Then
num1(0) = 0 '0位数所含1总数为0,这个可以作为公理吧
For i = 1 To 9 '2-9位数
num1(i) = num1(i - 1) * 10 + 10 ^ (i - 1)
Next
End If
s = 0
m = n
For i = 1 To 10
mmod = (m Mod 10)
If mmod = 0 Then
ElseIf mmod = 1 Then
' i-1位数总和 本位1 余数
s = s + (m Mod 10) * num1(i - 1) + 1 + ((n Mod 10 ^ (i - 1)))
Else
' i-1位数总和 余数
s = s + (m Mod 10) * num1(i - 1) + 10 ^ (i - 1)
End If
m = m / 10
If m = 0 Then Exit For
Next i
f = s
End Function
'用2分法查找the next biggst
Private Function GetNum() As Long
Dim i As Long, j As Long
Dim High As Double, Low As Double, Mid As Long
High = 2147483647
Low = 1000000000
Do
Mid = (High + Low) / 2
GetNum = f(Mid)
If GetNum > Mid Then
High = Mid
ElseIf GetNum < Mid Then
Low = Mid
Else
Exit Do
End If
Loop
End Function
用GetNum可以得到那个数:1111111110