编程之美---求1的数目

问题描述:

给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。
例如:
N=2,写下 1,2。这样只出现了 1 个“1”。
N=12,我们会写下 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12。这样 1 的个数是 5。
问题是:
1. 写一个函数f(N),返回1到N之间出现的“1”的个数,比如f(12)=5。
2. 在32位整数范围内,满足条件“f(N)= N”的最大的N是多少?

问题1求解:

#include <iostream>
using namespace std;
/*解法1:O(NlgN)从1~N遍历法。
依次遍历1~N中每一个数,先模10,若余数为1则sum++;
再除10,直到商为0,移到下一个要遍历的数字*/
int Count1InInteger1(int n)
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        int j=i;
        while(j)
        {
            if(j%10==1)
            {
                sum++;
            }
            j=j/10;
        }
    }
    return sum;
}
/*解法2:输入长度为len的数字,其时间复杂度为O(len)
总结一般情况下的计算方法:
假设N=abcde,对于百位来说受到三个方面的影响,更高位,百位,低位三者的影响.
1、c为0时,百位出现1的次数只由更高位决定,为(ab)* 100。
2、c为1时,百位出现1的次数由更高位和低位决定,为(ab)* 100 + cd + 1
3、c大于1时,百位出现1的次数只由更高位决定,为(ab+1)* 100
百位的规律对于其他数位同样适用.
*/
int Count1InInteger2(int n)
{
    int count = 0;
    int lowerNum = 0;
    int currNum = 0;
    int higherNum = 0;
    int factor = 1;
    while(n / factor != 0)
    {
        lowerNum = n-(n/factor)*factor;
        currNum = (n/factor)%10;
        higherNum = n/(factor*10);
        switch(currNum)
        {
            case 0:
                count += higherNum * factor;
                break;
            case 1:
                count += higherNum * factor + lowerNum + 1;
                break;
            default:
                count += (higherNum + 1) * factor;
                break;
        }
        factor = factor * 10;
    }
    return count;
}
int main()
{
    int n1=2,n2=12;
    cout<<"******************解法1***********************"<<endl;
    cout<<"N="<<n1<<"时,出现1的个数为:"<<Count1InInteger1(n1)<<endl;
    cout<<"N="<<n2<<"时,出现1的个数为:"<<Count1InInteger1(n2)<<endl;
    cout<<"******************解法2***********************"<<endl;
    cout<<"N="<<n1<<"时,出现1的个数为:"<<Count1InInteger2(n1)<<endl;
    cout<<"N="<<n2<<"时,出现1的个数为:"<<Count1InInteger2(n2)<<endl;
    return 0;
}

执行结果:

******************解法1***********************
N=2时,出现1的个数为:1
N=12时,出现1的个数为:5
******************解法2***********************
N=2时,出现1的个数为:1
N=12时,出现1的个数为:5

问题2求解:

得出n=1 111 111 110是满足f(n) = n的最大整数。详见编程之美p136解法分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值