一本书的页码从自然数1开始顺序编码直到自然数 n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字 0。例如,第 6 页用数字 6 表示,而不是 06 或 006 等。数字计数问题要求对给定书的总页码 n,计算出书的全部页码中分别用到多少次数字 0,1,2,…,9。
给定表示书的总页码的 10 进制整数 n (1≤n≤109) 。计算书的全部页码中分别用到多少次数字0,1,2,…,9。
根据n的范围,考虑使用unsigned long 类型
(1)统计0的个数
例:108
个位上出现0的次数为108/10=10
十位上出现0的次数为108-(10*10)+1=9
共19次
例:118
个位上出现0的次数为118/10=11
十位上出现0的次数为10
共21次
例:208
个位上出现0的次数为208/10=20
十位上出现0的次数为10+208-(20*10)+1=19
共39次
伪代码如下
cur_num=n;
mult=1;
q=0;
r=0;
while(cur_num)
{
q=cur_num/10;
r=cur_num%10;
if(q>0 && r>0)
cnt+=q*mult;
else if(q>0 && r==0)
cnt+=n-cur_num*mult+1;
if(q>1 && r==0)
cnt+=(q-1)*mult;
mult*=10;
cur_num/=10;
}
例:108
mult=1 q=10 r=8 cnt+=10
mult=10 q=1 r=0 cnt+=108-10*10+1=9
mult=100 q=0 r=1 cnt+=0;
cnt=19
例:118
mult=1 q=11 r=8 cnt+=11
mult=10 q=1 r=1 cnt+=q*mult=10
mult=100 q=0 r=1 cnt+=0;
cnt=21
例:208
mult=1 q=20 r=8 cnt+=20
mult=10 q=2 r=0 cnt+=(208-20*10+1)+(2-1)*10=19
mult=100 q=0 r=2 cnt+=0;
cnt=39
(2)统计1的次数
例:108
个位上1的次数为10+1
十位上1的次数为10
百位上1的次数为9
共30次
mult=1 q=10 r=8 cnt+=10*1+1=11
mult=10 q=1 r=0 cnt+=1*10=10
mult=100 q=0 r=1 cnt+=108-1*100+1=9
cnt=30
例:118
个位上1的次数为11+1=12
十位上1的次数为10+(118-110+1)=19
百位上1的次数为118-100+1=19
共50次
mult=1 q=11 r=8 cnt+=11*1+1=12
mult=10 q=1 r=1 cnt+=1*10+118-110+1=19
mult=100 q=0 r=1 cnt+=118-1*100+1=19
cnt=50 while(cur_num)
{
quotient=cur_num/10;
remainder=cur_num%10;
cnt+=quotient*mult;
if(remainder>1)
cnt+=mult;
else if(remainder==1)
cnt+=n-cur_num*mult+1;
mult*=10;
cur_num/=10;
}
(3)统计其他数的次数
和1类似
最终代码如下:
#include<stdio.h>
void Count(unsigned long n);
int main()
{
unsigned long n;
scanf("%ld",&n);
Count(n);
return 0;
}
void Count(unsigned long n)
{
unsigned long cur_num=n;
int cnt[10]={0};
int mult=1;
unsigned long quotient=0;
unsigned long remainder=0;
int temp=0;
int i;
while(cur_num)
{
quotient=cur_num/10;
remainder=cur_num%10;
if(quotient>0 && remainder>0)
cnt[0]+=quotient*mult;
else if(quotient>0 && remainder==0)
cnt[0]+=n-cur_num*mult+1;
if(quotient>1 && remainder==0)
cnt[0]+=(quotient-1)*mult;
for(i=1;i<=9;i++)
{
cnt[i]+=quotient*mult;
if(remainder>i)
cnt[i]+=mult;
else if(remainder==i)
cnt[i]+=n-cur_num*mult+1;
}
mult*=10;
cur_num/=10;
}
for(i=0;i<=9;i++)
printf("%d\n",cnt[i]);
}