计算1到N的十进制数中1的出现次数
轉自: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;
}
總結
以上是生活随笔為你收集整理的计算1到N的十进制数中1的出现次数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stl删除操作
- 下一篇: stringstream和cin