一、题目
给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。
二、要求
写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12) = 5。在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。
三、设计思路
1、首先遍历每个数的各个位数,然后将1的个数加起来。
2、首先找规律: f(1)=1;f(13)=7=2+5;f(23)=13=3+10......f(abcde)=?
以百位为例, 当c是1,那么百位上1的个数是由他的高位和低位来决定的。等于ab*100+cde+1;当c是"0",那么百位上1的个数是ab*100;当c是大于1,那么 百位上1的个数是(ab+1)*100;以此类推。
四、源代码
1.遍历各位1的个数:
#include<iostream> using namespace std; int main() {int icount=0,i,N,temp; cout<<"请输入最大的数N:"; cin>>N; for(i=1;i<=N;i++) { temp=i; while(temp!=0) { icount+=(temp%10==1)?1:0; temp/=10; } } cout<<icount<<endl; return 0; }
2.通过规律的:
#include<iostream.h> int Count(int n) { int count=0; int now=1; int l=0; int nownum=0; int h=0; if(n<=0) { return 0; } while(n/now!=0) { l=n-(n/now)*now; nownum=(n/now)%10; h=n/(now*10); if(nownum==0) { count+=h*now; } else if(nownum==1) { count+=h*now+l+1; } else { count+=(h+1)*now; } now*=10; } return count; } void main() { int number; cout<<"请输入数字:"; cin>>number; cout<<Count(number)<<endl; }
五、实验截图
六、实验总结
这道题刚发下来,感觉不是很难,不就是遍历1的个数,但是老师需要我们将一个个数算出来,然后找规律,然后就发现问题了。原来问题不是非用很复杂的算法才能解决,简单的也可以算出来,以前的问题是把简单的算法优化,得到复杂的,今天是把复杂的,用简单的算法来实现,不知道有什么太大用处,我还是觉得那句话对,首先能把目的实现的程序就是好程序。