天天看点

1的数目

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.结果:

1的数目
1的数目
1的数目

5.总结:

当遇到一个程序时,不能只看着,要动手画,找出其中的规律,在代码实现时要注意程序运行的效率问题,不能只写出来就行了。