2027 - 统计数字
Time Limit : 1 秒
Memory Limit : 128 MB
一本书的页面从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6页用数字6表示,而不是06或006等。现在要求你对给定书的总页码n,计算出书的全部页码分别用到多少次数字0,1,2,...,9.
Input
有若干组数据,每组数据一行。
每行一个数字n。(1≤n≤10^9)
Output
每组输入数据对应10行。分别是0-9的使用次数。
输出完一组数据后,额外输出一个换行。
Examples
Input Format
11 1
Output Format
1 4 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0
Solution C
//方法3 #include <stdio.h> int main() { int i,j,a; while((scanf("%d",&a)!=EOF)&&(1<=a&&a<=1000000000)){ long int count[10]={0}; int c,k,s,wei; for(k=s=0,wei=1;a>0;k++,a/=10,wei*=10) { c=a%10; for(i=0;i<10;i++) count[i]+=c*k*(wei/10); for(i=0;i<c;i++) count[i]+=wei; count[c]+=1+s; count[0]-=wei; s+=c*wei; } for(j=0;j<10;j++){ printf("%d\n",count[j]); } printf("\n"); } return 0; }
Solution C++
#include <iostream> #include <time.h> using namespace std; int s[10]; //记录0~9出现的次数 int a[10]; //a[i]记录n位数的规律 //l是位数,m是当前处理位(高->低) void sum(int n,int l,int m) { //去除前缀0 if(m==1) { int zero=1; for(int i=0;i<=l;i++) { s[0]-=zero; zero*=10; } } //位数为1位时,出现次数加1 if(n<10) { for(int i=0;i<=n;i++) { s[i]+=1; } return; } //位数大于1时的出现次数 //计算规律f(n)=n*10^(n-1) for(int t=1;t<=l;t++) { m=1; for(int i=1;i<t;i++)m=m*10; a[t]=t*m; } //求出输入数为10的n次方 int zero=1; for(int i=0;i<l;i++) { zero*= 10; } //求出最高位以后的数 int yushu=n%zero; //求出最高位zuigao int zuigao=n/zero; //求出0~zuigao-1位的数的出现次数 for(int i=0;i<zuigao;i++) { s[i]+=zero; } //求出与余数位数相同的0~zuigao-1位中0~9出现的次数 for(int i=0;i<10;i++) { s[i]+=zuigao*a[l]; } //如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数 //补上所缺的0数,并且最高位加1 if(yushu==0) { s[zuigao]++; s[0]+=l; } else { int i=0; while((zero/=10)>yushu) { i++; } s[0]+=i*(yushu+1);//补回因作模操作丢失的0 s[zuigao]+=(yushu+1);//补回最高位丢失的数目 sum(yushu,l-i-1,m+1);//处理余位数 } } int main() { int i,m,n,N,l; while(cin>>N) { for(i=0; i<10; ++i) { a[i] = 0; s[i] = 0; } n = N; //求出N的位数i+1 for(i=0;n>=10;i++) { n/=10; } l=i; //cout<<"位数:"<<l<<endl; sum(N,l,1); for(i=0;i<10;i++) { //cout <<"数字" <<i <<"出现了:"<<s[i]<<"次"<<endl; cout << s[i] << endl; } cout << endl; } return 0; }