问题描述:
给定一个十进制整数n,表示书的总页码数,计算书的页码中分别用到多少次数字0,1,2, ....,9。
如输入11 得到 : 1,4,1,1,1,1,1,1,1,1
解法1:时间复杂度为 O(n* log n)
void handler(int *a, int i)
{
int r;
while(i)
{
r=i%10;
a[r]++;
i=i/10;
}
}
int main(void)
{
int a[11];
int n;
int i=0;
for(i=0;i<10;i++)
a[i]=0;
cin>>n;
for(i=1;i<=n;i++)
handler(a,i);
for(int k=0;k<10;k++)
cout<<a[k]<<" ";
}
解法2:时间复杂度为 O( log n)
分析如下:
由0到9组成的n位数,从n个0到n个9,在这10^n个n位数中,0,1,2,......,9 每个数字都使用相同次数,设为f(n)。
f(n)满足:
10f(n-1) + 10^(n-1) n>1
f(n) =
1 n=1
所以,f(n)=n*10^(n-1)
举例:
假如书页码数为21345。则包含了2个 0000~9999区间,即 0000~9999和 10000~19999。每个数字出现次数为2*f(4)。而多余的前导0出现在区间 0000~9999中。0000~0999中,有1000个。000~099中,有100个。00~09中,有10个。加上第一个0。
最高位数字为1,出现了10000次。因为10000~19999。接着计算20000~21345,2出现了1346次。于是,着眼点就落在0000~1345中各数字的出现次数上,此时依照上面的取区间法,一次一次去掉最高位,直到剩下个位时为止。