整數中1出現的次數(從1到n整數中1出現的次數)
阿新 • • 發佈:2019-03-05
blank 特殊情況 你們 描述 允許 acm terminal cell des
來源:牛客網
題目描述
求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。當n = 3141592時:
<thead></thead>m | a | b | ones |
---|---|---|---|
1 | 3141592 | 0 | (3141592+8)/10*1+0=314160 |
10 | 314159 | 2 | (314159+8)/10*10+0=314160 |
100 | 31415 | 92 | (31415+8)/10*100+0=314200 |
1000 | 3141 | 592 | (3141+8)/101000+1(592+1)=314593 |
當然後面還有m=10000,100000,1000000三種情況,對應著萬位,十萬位, 百萬位為1時的情況
下面說下a+8的意義:
當考慮個位,十位,百位這三位為1的情況時:
個位 2 ,當個位取值1時,前面的六位數字可由0~314159組成,即314160種情況
十位9,當十位取值1時,前面的五位數字可由0~31415組成,十位之後的一位可由0~9組成,組合情況31416*10=314160種情況
百位5,當百位取值為1時,前面的四位數字可由0~3141組成,百位之後的兩位可由0~99組成,組合情況為3142*100=314200種情況
註意:當考慮千位1時:
千位1,千位取值即1,前面的三位數字可由0~314組成,但是當前面的值為314時,後面的三位只有0~592種情況(特殊情況),其余的情況即為前面的值為0~313,後面三位有0~999,情況數為3141000,所以總情況數為3141000 + 593=314593種情況
這時可發現和代碼中的公式算的情況是吻合的,a+8的巧妙之處在於當a的最後一位(當前分析位)為0或1時,加8不產生進位,這是為需要單獨算的特殊情況做準備,而當前分析位為2~9時,不需要考慮特殊情況,所以允許加8產生的進位。
鏈接:https://www.nowcoder.com/questionTerminal/bd7f978302044eee894445e244c7eee6
int countDigitOne(int n) { int ones = 0; for (long long m = 1; m <= n; m *= 10) { int a = n/m, b = n%m; ones += (a + 8) / 10 * m + (a % 10 == 1) * (b + 1); } return ones; }
整數中1出現的次數(從1到n整數中1出現的次數)