1.题目:
给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。
要求:
写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12) = 5。
在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。2.设计思路:
刚开始时想的是遍历N以内的所有数,将出现1的次数相加便得到结果,但是这种算法时间复杂度比较大,不适合第二个要求。后来又找规律。
N=13 f(N)=2+4=6;
N=23 f(N)=3+10=13;
N=33 f(N)=4+10=14;
.......
N=93 f(N)=10+10=20;
所以可以将数字按位数分情况。
3.源代码:
#include<iostream> using namespace std; int Count(long n){ long count = 0; long n1 = 1; int nN = 0; int gN = 0; int hN = 0; if (n <= 0){ return 0; } while (n / n1 != 0){ nN = n - (n / n1)*n1; gN = (n / n1) % 10; hN = n / (n1 * 10); if (gN == 0){ count += hN*n1; } else if (gN == 1){ count += hN*n1 + nN + 1; } else { count += (hN + 1)*n1; } n1 *= 10; } return count; } int main(){ int a; cin >> a; cout<<Count(a); int i; for (i = 0; i < 2147483647; i++) { if (Count(i) == i) { cout << i << endl; } } return 0; }
4.结果:
5.总结:
当遇到一个程序时,不能只看着,要动手画,找出其中的规律,在代码实现时要注意程序运行的效率问题,不能只写出来就行了。