现在的位置: 首页 > 综合 > 正文

计算1到N的十进制数中1的出现次数

2018年12月13日 ⁄ 综合 ⁄ 共 1701字 ⁄ 字号 评论关闭

转自:http://hi.baidu.com/zhaoshengjin/blog/item/f1df6618cb1debbe4bedbc5d.html

问题描述:给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有"1"的个数。例如:
N = 2,写下1,2。这样只出现了1个"1"。
N = 12,写下1,2,……,12,这样有5个"1"。
写一个函数f(N),返回1到N之间出现的"1"的个数,比如f(12) = 5。

    假设N = abcde,这里a,b,c,d,e分别是十进制数N的各个数位上的数字。如果要计算百位上出现1

的次数,将受3方面因素影响:百位上的数字,百位以下(低位)的数字,百位(更高位)以上的数字。

    如果百位上的数字为0,则可以知道百位上可能出现1的次数由更高位决定,比如12 013,则可以知

道百位出现1的情况可能是100-199,1 100-1 199,……,11 100-11 199,一共有1 200个。也就是

由更高位数字(12) 决定,并且等于更高位数字(12)×当前位数(100)。

    如果百位上的数字为1,则可以知道,百位上可能出现1的次数不仅受更高位影响,还受低位影响,

也就是由更高位和低位共同决定。例如12 113, 受更高位影响,百位出现1的情况是100-199,1 100

-1 199,……,11 100-11 199,一共有1 200个,和上面第一种情况一样,等于更高位数字(12)×当

前位数(100)。但它还受低位影响,百位出现1的情况是12 100-12 113,一共14个,等于低位数字

(13)+1。一共为1200+14 = 1214.

   如果百位上数字大于1(即为2-9),则百位上可能出现1的次数也仅由更高位决定,比如12 213,则

百位出现1的情况是:100-199,1 100-1 199,……,11 100-11 199,12 100-12 199,共1300个

,并且等于更高位数字+1(12+1)×当前位数(100)。

今天百度之星的第二题就是求几个数出现的次数,比如求12388以内以88结尾的所有数的数量,如果最后两位>=88则数量为123+1,但是如果最后两位<88,数量为123。一定要谨慎,多少次教训了!

按照位来统计在这个位上所有的1的个数

#include <iostream>
#include <windows.h>
using namespace std;

LONGLONG Sum1s( ULONGLONG n )
{
    ULONGLONG iCount = 0;
    ULONGLONG iFactor = 1;

    ULONGLONG iLowerNum = 0;
    ULONGLONG iCurrNum = 0;
    ULONGLONG iHigherNum = 0;

  //从数n的最低位开始,n/iFactor表示的是当前处理的数的数值

//譬如数1234,则n/iFactor依次表示 1234,123,12,1

    while( n / iFactor != 0 )
    {
        iLowerNum = n - ( n / iFactor ) * iFactor;
        iCurrNum = (n / iFactor ) % 10;
        iHigherNum = n / ( iFactor *10 );

        switch( iCurrNum )
        {
        case 0:
            iCount += iHigherNum * iFactor;
            break;
        case 1:
            iCount += iHigherNum * iFactor + iLowerNum + 1;
            break;
        default:
            iCount += ( iHigherNum + 1 ) * iFactor;
            break;
        }

        iFactor *= 10;
    }
    return iCount;
}

int main()
{
    cout << Sum1s(100000000);

    cin.get();    
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.