统计数字问题
2013-08-29 13:16
246 查看
问题描述:
一本书的页码从自然数1开始计数,直到自然数n。书的页码按照通常的习惯编排,每个页码都不包含多余的前导数字0。例如,第6页用数字6表示,而不是06或006等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,...,9。
方法1解题思路:
暴力求解。本题关键在于将每一页码的数字进行分解,这种方式可以利用整数的除法和对10取余计算。例如,对于数的分解过程可以采用如下方式进行:
解题思路2:
考虑一个数字12345,在个数上,数字出现的频率是1次,即0到9不断循环出现;而在10位数字上,每个数字是连续出现10次后再出现另一个数字;百位数字上依此类推……
基于这个思路,如果我们能计算出0到9这10个数字在每一位上出现的次数,对它们进行求和, 即可计算出这10个数字出现的次数。
考虑**X**,在第3位上统计相关数字出现的次数。一般地,数字出现的次数与X的大小有直接的有关系。
(1)如果数字比X大,则它在这一位上出现的次数与前面的数字和该数字所在的位置有关。例如,12345中,数字4在第3位出现的次数为:
12*100=1200
(2)如果数字等于X,则它在这一位上出现的次数与前面的数字、后面的数字和该数字所在的位置有关。例如,12345中,数字3在第3位上出现的次数为:
12*100+45+1=1246
(3)如果数字小于X,则它在这一位上出现的次数与前面的数字和该数字所在的位置有关。例如,12345中,数字2在百位上出现的次数为
(12+1)*100=1300
按照这个思路编写的程序如下所示:
解题思路3:
给定一个n位数字number,我们首先看一下从0到最大的n位数字,如果位数不够,在前面填0,这样一共有10^n个数字,其中包含数字的个数是n*10^n,其中包含这10个数字是相同的,都为n*10^{n-1}位。
能否根据这一思路,从高位到低位依次处理?得到最终的位数?可以首先把最高位的数字单独处理,然后再处理其他的n-1位,最后把那些多余的0全部去掉就可以了。
一本书的页码从自然数1开始计数,直到自然数n。书的页码按照通常的习惯编排,每个页码都不包含多余的前导数字0。例如,第6页用数字6表示,而不是06或006等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,...,9。
方法1解题思路:
暴力求解。本题关键在于将每一页码的数字进行分解,这种方式可以利用整数的除法和对10取余计算。例如,对于数的分解过程可以采用如下方式进行:
while(n>0) { printf(“%d”, n%10); n=n/10; }
#include<stdio.h> void main() { int n; int i; int number[10]; //借用数组存储每一个10进制数的出现次数 //对出现次数进行初始化 for(i=0;i<10;i++) number[i]=0; printf("pleaseinput the number of pages in the given book:"); scanf("%d",&n); //将数进行位分解,将对应数的出现次数加1 for(i=1;i<=n;i++) { int j,temp; temp=i; while(temp>0) { number[temp%10]++; temp=temp/10; } } //输出 for(i=0;i<10;i++) printf("%d",number[i]); printf("\n"); }
解题思路2:
考虑一个数字12345,在个数上,数字出现的频率是1次,即0到9不断循环出现;而在10位数字上,每个数字是连续出现10次后再出现另一个数字;百位数字上依此类推……
基于这个思路,如果我们能计算出0到9这10个数字在每一位上出现的次数,对它们进行求和, 即可计算出这10个数字出现的次数。
考虑**X**,在第3位上统计相关数字出现的次数。一般地,数字出现的次数与X的大小有直接的有关系。
(1)如果数字比X大,则它在这一位上出现的次数与前面的数字和该数字所在的位置有关。例如,12345中,数字4在第3位出现的次数为:
12*100=1200
(2)如果数字等于X,则它在这一位上出现的次数与前面的数字、后面的数字和该数字所在的位置有关。例如,12345中,数字3在第3位上出现的次数为:
12*100+45+1=1246
(3)如果数字小于X,则它在这一位上出现的次数与前面的数字和该数字所在的位置有关。例如,12345中,数字2在百位上出现的次数为
(12+1)*100=1300
按照这个思路编写的程序如下所示:
#include "stdio.h" #include "math.h" int main() { int n,i,j,k,len; int tempNum, lower, higher; int count[10]={0}; printf("please input the number n:"); scanf("%d",&n); len=log10(n); for(i=0;i<=len;i++) { tempNum=(n/(int)pow(10,len-i))%10; higher=n/(int)pow(10,len-i+1); lower=n%(int)pow(10,len-i); count[tempNum]+=lower+1; for(j=0;j<tempNum;j++) count[j]+=(int)pow(10,len-i)*(higher+1); for(j=tempNum;j<10;j++) count[j]+=(int) pow(10,len-i)*higher; } for(i=0;i<=len;i++) count[0]-=(int)pow(10,i); for(i=0;i<10;i++) { printf("%d ",count[i]); } return 1; }
解题思路3:
给定一个n位数字number,我们首先看一下从0到最大的n位数字,如果位数不够,在前面填0,这样一共有10^n个数字,其中包含数字的个数是n*10^n,其中包含这10个数字是相同的,都为n*10^{n-1}位。
能否根据这一思路,从高位到低位依次处理?得到最终的位数?可以首先把最高位的数字单独处理,然后再处理其他的n-1位,最后把那些多余的0全部去掉就可以了。
#include <stdio.h> #include <math.h> int main() { int n,tempN, i,j,k,higher,rest,len,count[10]={0}; printf("input the pages:"); scanf("%d",&n); len=log10(n); tempN=n; for(i=0;i<=len;i++) { higher=tempN/pow(10,len-i); //取得最高位 rest=tempN-higher*pow(10,len-i); count[higher]+=rest+1; for(j=0;j<higher;j++){ count[j]+=pow(10,len-i); for(k=0;k<10;k++) count[k]+=(len-i)*pow(10,len-i-1); } tempN=rest; } for(i=0;i<=len;i++) count[0]-=pow(10,i); for(i=0;i<10;i++) printf("%d ",count[i]); return 1; }