回复 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; }