问题描述:输入页码n后计算数字0-9出现的次数,对于类似于06的页码,不计算0,只计算6。
采取递归的方式:
1.对于类似于06的页码,先计算上0,等后续再删掉。
2. 0-9 页,0-9各出现1次;
0-99 页,0-9各出现2*(10^1)次;
0-999页,0-9各出现3*(10^2)次……
(对于一个三位数□□□,以数字1出现的次数为例:
1位于百位时,0-9的可以出现在十位、个位,即10^2次;
1位于十位时,0-9的可以出现在百位、个位,即10^2次;
1位于个位时,0-9的可以出现在百位、十位,即10^2次;
所以各个数字出现的次数为:
位数*10^(位数-1)。)
一、找页数n的位数:int weishu=log10(n)+1;
二、对页数n进行区间划分+统计数字
1.
以2127为例,考虑2127区间数。
0000-0999 √
1000-1999 √
由于2000-2999超过2127,故不考虑该区间。
以上每个区间除千位数外0-9各出现300次,
区间数为n/10^(weishu-1)取整,
即2127/10^3=2,另外区间数与该数2127的最高位一致均为2,定义:
int zuigaowei=n/(int)pow(10.0,weishu-1);
除最高的千位数外,0-9总共出现2*(4-1)*10^(4-2)次,即 区间数*(位数-1)*10^(位数-2)。
a[i]+=zuigaowei*(weishu-1)*(int)pow(10.0,weishu-2);
最高位千位出现次数,0:1000次;1:1000次。
for (int i=0;i<zuigaowei;i++)
{
a[i]+=(int)pow(10.0,weishu-1);
}
2.
2127/10^3取余为127,故以下考虑127区间数。
000-099 √
因为100-199超过127,故不考虑该区间 。
以上每个区间除百位数外0-9各出现20次,
区间数为127/10^2=1,与该数127最高位一致。
除最高的百位数外,0-9总共出现1*(3-1)*10^(3-2)次,即 区间数*(位数-1)*10^(位数-2)。
最高位百位出现次数:0:100次。
对于千位数的2,出现127+1=128次。
int yu=n%int(pow(10.0,weishu-1));
a[zuigaowei]+=1+yu;
3.
127/10^2取余为27,故以下考虑27区间数。
00-09;√
10-19;√
以上每个区间除十位数外0-9各出现1次,
区间数为27/10^1=2,与该数27最高位一致。
除最高的十位数外,0-9总共出现2*(2-1)*10^(2-2)次,即 区间数*(位数-1)*10^(位数-2)。
最高位十位出现次数:0:10次;1:10次。
对于百位数上的1,出现27+1=28次。
4.
20-27单独考虑。
最高位0-7上的数字出现10^(位数-1)次,即各一次。
对于十位数上的2,27/10^1余数为7,出现7+1=8次。
三、考虑余数为0的情况
如3000
if(yu==0) //如3000
{
a[0]+=weishu-1;
a[zuigaowei]++;
return;
}
四、减去多余的0
应减去0的个数为10^0+10^1+10^2……10^(位数-1)。
五、代码
#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[10];
void solve(int n)
{
int weishu=log10(n)+1;
int zuigaowei=n/((int)(pow(10.0,weishu-1)));
for (int i=0;i<10;i++)
{
a[i]+=zuigaowei*(weishu-1)*(int)pow(10.0,weishu-2);
}
for (int i=0;i<zuigaowei;i++)
{
a[i]+=(int)pow(10.0,weishu-1);
}
int yu=n%int(pow(10.0,weishu-1));
int weishut=log10(yu)+1;
if(yu==0) //如3000
{
a[0]+=weishu-1;
a[zuigaowei]++;
return;
}
a[zuigaowei]+=1+yu;
return solve(yu);
}
int main()
{
int n;
while (cin>>n)
{
fill (a,a+10,0);
int weishu=log10(n)+1;
solve(n);
for (int i=0;i<weishu;i++)
{
a[0]-=(int)pow(10.0,i);
}
for(int i=0;i<10;i++)
{
cout<<i<<"出现次数为:"<<a[i]<<endl;
}
}
}