计数的梦

来源:百度知道 编辑:UC知道 时间:2024/09/22 09:48:48
RQNOJ上的一道题:
Bessie 处于半梦半醒的状态。过了一会儿,她意识到她好像在数羊,不能入睡。Bessie的大脑反应灵敏,仿佛真实地看到了她数过的一个又一个数。她开始注意每一个数码:每一个数码在计数的过程中出现过多少次?
给出两个整数 M 和 N (1 <= M <= N <= 2,000,000,000 以及 N-M <= 500,000),求每一个数码出现了多少次。
例如考虑序列 129..137: 129, 130, 131, 132, 133, 134, 135, 136, 137。统计后发现:
1x0 1x5
10x1 1x6
2x2 1x7
9x3 0x8
1x4 1x9
输入格式
共一行,两个用空格分开的整数 M 和 N
输出格式
共一行,十个用空格分开的整数,分别表示数码(0..9)在序列中出现的次数。
样例输入
129 137
样例输出
1 10 2 9 1 1 1 1 0 1
我的程序:
#include<stdio.h>
long long p(int i)
{
int k,d=1;
for (k=1;k<=i;k++)
d*=10;
return(d);
}
int l(long long m)
{
int i;
for (i=1;;i++)
if (p(i)<=m&&p(i+1)>m)
break;
return(i);
}
main()
{
int a[10]={0},j,t,k;
long long m,n,i,b[10]={0};
scanf("%I64d%I64d",&m,&n);
for (i=l(m);i>=0;i--)

你的l函数里面写的有问题 if (p(i)<=m&&p(i+1)>m) 这句, 如果m等于1呢?p(i)最少都是从p(1)开始,而p(1) = 10,所以如果m<10,会算到p(i)溢出才能停止,结果显然会错误。

其实根本不用那么麻烦, 把一个整数转成数组,下面一行代码就可以
while (tt) a[i++] = tt%10, tt/=10;

修正后的程序如下:
#include<stdio.h>
main()
{
int a[10]={0},j,t,k;
long long m,n,i,b[10]={0}, tt;
scanf("%I64d%I64d",&m,&n);
i = 0, tt = m;
while (tt) a[i++] = tt%10, tt/=10;
for (i=m;i<=n;i++)
{
for (k=0,j=9;j>=0;j--)
{
if (a[j]!=0) k=1;
if (k) b[a[j]]++;
}
for (j=0,t=1;j<=9;j++)
{
a[j]+=t;
t=a[j]/10;
a[j]%=10;
if (!t)
break;
}
}
for (i=0;i<=9;i++)
{
printf("%I64d",b[i]);
if (i-9)