统计数字问题
来源:互联网 发布:opengl es2.0编程指南 编辑:程序博客网 时间:2024/04/30 15:46
最近有些堕落了。 要赶紧调整过来。 先写篇解题报告试试。。。
题目描述:
一本书的页码从自然数1开始顺序编码直到自然数N。书的页码不包含前导数字0。例如,第6也用数字6表示,而不是06。要求给定书总页码n。计算书的全部页码中分别用到多少次数字0,1,2,3,4…9.
输入 10 输出 1 4 1 1 1 1 1 1 1 1
为了方便考虑, 补全前导0。 考察由0,1,……9组成的所有n位数 。从n个0到n个9。共10^n个n位数。其中每个数字出现相同的n*10^(n-1)次。现在利用这个结论来举个例子计算一下334。
从000到334。 首先考虑从00到99,100到199 200到299中个位和十位上每个数字出现了3*10 次(先不考虑百位)。然后考虑百位上0,1,2,3 这四个数分别出现多少次,很明显,0,1,2 分别出现100次,3 出现了35次(34+1)。 计算完这些之后,现在只有从00到34上数字出现的次数没考虑了。同样的方法,计算00到34,首先考虑0到9 10到19 20 到29 个位上每个数字出现3*1次。百位上0,1,2分别出现10次,3 出现5次(4+1)。 计算完这些后,只剩下从0到4 上数字出现的次数需要考虑了,这就很明显了。计算完之后,还需要将前导0减掉。前导0的出现是很有规律的,比如说000到334,我们增加的前导0的个数为3+2*9+1*90=111。可以注意到整个算法具有很明显的相似子结构,可以用递归来做,但同样用循环也是可以实现的。
代码如下:
#include <stdio.h>
#include <string.h>
int ans[12],bs[12],f[12];
int reduce(int n)//计算前导0的个数
{
int count=0,i,j;
for(i=1;i<n;i++){
count=count+(n-i)*9*bs[i-1];
}
return count+n;
}
int cnt(char val[],int l,int len)
{
int count=0;
for(int i=l;i<len;i++){
count=count*10+val[i]-'0';
}
return count+1;
}
int main()
{
int len,i,j;
char val[11];
for(i=1,bs[0]=1;i<10;i++){
bs[i]=bs[i-1]*10;
}
for(i=1,f[0]=0;i<10;i++){
f[i]=10*f[i-1]+bs[i-1];
}
while(scanf("%s",val)!=EOF){
len=strlen(val);
memset(ans,0,sizeof(int)*10);
for(i=0;i<len;i++){
int wei=len-i,v=val[i]-'0';
for(j=0;j<10;j++){
ans[j]=ans[j]+v*f[wei-1];
}
for(j=0;j<v;j++){
ans[j]=ans[j]+bs[wei-1];
}
ans[v]=ans[v]+cnt(val,i+1,len);
}
ans[0]=ans[0]-reduce(len);
for(i=0;i<10;i++){
printf("%d/n",ans[i]);
}
}
return 0;
}
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 统计数字问题
- 大洋蛋...要走了...倒数359...
- Win7首个动态主题 可自动获取Bing新壁纸
- C++ Traits
- hibernate之多态关联(多态的多对一关联或者多态的一对一关联,利用joined-subclass)
- 资源_C++编码缩写命名
- 统计数字问题
- linux的共享库(动态链接库)
- hibernate之多态关联(多态的一对多,利用joined-subclass)
- 想说写什么!想说写什么!
- 想说写什么!
- flex教程:内存使用机巧
- 用curl抓取数据
- 一个根据.BOM文件自动创建Excel BOM的程序---记录在此,以便查询
- using(C# 参考