问题描述:
一本书的页码从自然数1开始计数,直到自然数n。书的页码按照通常的习惯编排,每个页码都不包含多余的前导数字0。例如,第6页用数字6表示,而不是06或006等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,...,9。
方法一: 暴力(适用于数据较小和打表检验自己的结果是否正确)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL f[10],f1[10];
LL ans[10];
int main()
{
ios::sync_with_stdio(false);
LL n;
while(cin >> n)
{
memset(ans,0,sizeof(ans));
for(int i=1;i<n;i++)
{
LL m=i;
while(m)
{
ans[m%10]++;
m/=10;
}
}
for(int i=0;i<10;i++)
{
cout << ans[i] << endl;
}
}
return 0;
}
方法二:计算每位上每个数字出现的次数(推荐)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL arr[110],arr1[110];
int main()
{
LL n;
while(cin >> n)
{
memset(arr,0,sizeof(arr));
LL m=n;
LL z=1;
while(m)
{
LL d=m%10;
m=m/10;
for(int i=0;i<10;i++)
{
arr1[i]=m;
}
for(int i=1;i<d;i++)
{
arr1[i]++;
}
if(d==0) arr1[0]--;
for(int i=0;i<10;i++)
{
arr[i]+=arr1[i]*z;
}
arr[d]+=n%z+1;
z=z*10;
}
for(int i=0;i<10;i++ )
{
cout <<arr[i] <<endl;
}
}
return 0;
}
方法三: f(n)=n*10^(n-1)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL f[10],f1[10];
LL ans[10];
LL fh()
{
f[0]=0,f1[1]=1;
f[1]=1,f1[1]=1;
for(int i=2;i<10;i++)
{
f1[i]=f1[i-1]*10;
f[i]=10*f[i-1]+f1[i];
}
}
LL tj1(LL n,LL l)
{
if(l==1)
{
for(int i=1;i<=n;i++)
{
ans[i]++;
}
return 0;
}
for(int i=0;i<10;i++)
{
ans[i]+=n/f1[l]*f[l-1];
//cout << ans[i] <<endl;
}
//cout << "f" << endl;
for(int i=0;i<n/f1[l];i++)
{
ans[i]+=f1[l];
//cout <<i << " sadf "<< ans[i] <<endl;
}
//cout << n << f1[l] << endl;
ans[n/f1[l]]+=n%f1[l]+1;
//cout <<n/f1[l] << " sadf "<< ans[n/f1[l]] <<endl;
tj1(n%f1[l],l-1);
}
LL tj(LL n,LL l)
{
if(l==1)
{
for(int i=1;i<=n;i++)
{
ans[i]++;
}
return 0;
}
for(int i=0;i<10;i++)
{
ans[i]+=n/f1[l]*f[l-1];
//cout << ans[i] <<endl;
}
//cout << "f" << endl;
for(int i=0;i<n/f1[l];i++)
{
ans[i]+=f1[l];
//cout <<i << " sadf "<< ans[i] <<endl;
}
//cout << n << f1[l] << endl;
ans[n/f1[l]]+=n%f1[l]+1;
//cout <<n/f1[l] << " sadf "<< ans[n/f1[l]] <<endl;
//cout << ans[0]<< " dsf "<< endl;
for(LL i=l;i>1;i--)
{
ans[0]-=f1[i];
//cout <<i << " sadf "<< ans[i] <<endl;
}
tj1(n%f1[l],l-1);
}
int main()
{
ios::sync_with_stdio(false);
fh();
LL n;
while(cin >> n)
{
memset(ans,0,sizeof(ans));
LL m=n,l=0;
while(m)
{
l++;
m/=10;
}
tj(n,l);
for(int i=0;i<10;i++)
{
cout << ans[i] << endl;
}
}
return 0;
}