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.总结:
当遇到一个程序时,不能只看着,要动手画,找出其中的规律,在代码实现时要注意程序运行的效率问题,不能只写出来就行了。