回复 10楼 Magic_July
这么坚定地相信你的理解是对的么?为什么不提交一下小曹的代码试试呢?

重剑无锋,大巧不工
程序代码:#include <stdio.h>
#define M 9999
int main(void)
{
int c[M+1];//存储1~N里面1的个数
int num[M];//存储输入的数
int i,j,k=0,d,n;
for(i=1,d=0;i<=M;i++)
{
for(j=1;i/j;j*=10)
{
c[i]=d;
if(i/j%10==1)
c[i]=++d;
}
}//算出所以的数
printf("Input:\n");
while(scanf("%d",&n),n)
{
num[k]=n;
k++;
}
printf("\nOutput:\n");
for(i=0;i<k;i++)
{
printf("%d\n",c[(num[i])]);//输出1~已输入数n里面1的个数
}
return 0;
}
程序代码:#include"stdio.h"
int main()
{
int x[9999],i,j,d,N;
for(i=0,d=0;i<9999;i++)
{
for(j=1;i/j;j*=10)
{
if(i/j%10==1)
{x[d]=i;
if(x[d]==x[d-1])
x[d-1]==-1;
//printf("%d d=%d ",x[d],d);
d++;
}
}
}
while(scanf("%d",&N),N)
{
for(i=0;i<9999;i++)
{
if(N>=9991){printf("4000\n");break;}
if(x[i]<=N&&x[i+1]>N)
{
if(x[i]==-1)
continue;
else
printf("%d\n",i+1);break;}
}
}
return 0;
}
程序代码:
int num_1_rec(int n)
{
static int num_base[4] = {0, 0, 0, 1}; //分别存放0-9,99,999,9999中出现的1的个数
//个位数直接退出
if(n == 0) return 0;
else if(n < 10) return 1;
int base = 1, basepos = -1, i, nH, nL;
//求解n(>=10)的数基(Exp. 50的数基为10),以及其对应的num_base的下标位置
while((i = n/base) >= 10){
base *= 10;
basepos++;
}
//最高位产生的1的个数(Exp. 2523, 0-1999中1的个数)
nH = num_base[basepos] != 0 ? num_base[basepos] : num_1_rec(base-1);
nH *= i;
if(i > 1) nH += base;
else nH += n%base + 1; //最高位为1的情况的特殊处理
//低位产生的1的个数(Exp. 2523, 2000-2523[0-253]中1的个数)
nL = num_1_rec(n%base);
//保存已经计算过的0-9,99...中1的个数
if(n+1 == base*10) num_base[basepos+1] = nH+nL;
return nH+nL;
}
