51nod 1009 數字1的數量

2021-08-09 12:27:55 字數 1550 閱讀 7771

給定乙個十進位制正整數n,寫下從1開始,到n的所有正數,計算出其中出現所有1的個數。

例如:n = 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。

input

輸入n(1 <= n <= 10^9)
output

輸出包含1的個數
input示例

12
output示例

5
闊別很久,再次寫部落格......確實懶了,總之,部落格今天開始每天不定時更新。

這道題開始自己想錯了,以為很簡單,但發現沒考慮百位以上的1的個數,所以就很天真的交了2次......

意識到錯誤後發現自己確實不是很會,於是就去網上查了檢視了看別人的思路,有幾個大佬是直接找規律的.....所以**不是很懂,但還是有寫的非常明白的解釋了

寫一下解題思路:

這個題n很大,10^9,所以不能打表。我們就要採用比較高效的方法。

如果我們來考慮每乙個數,它一共有多少個1,這樣想會很麻煩,我剛開始用排列與組合寫了好久,發現到最高位的時候並不怎麼好寫。後來考慮另一種方法:

我們統計每個位置上可能出現1的數,這樣就把問題拆開了。

比如:12。個位上可能出現1的數為1,11(一共2個),十位上可能出現1的個數為10,11,12(一共3個),加一起正好是5。(至於11是否重複的問題,還是再理解一下上面的做法,這個做法只考慮了每一位出現1的數,11在個位上算和在十位上算是不一樣的,所以並沒有重複)。

那麼我們再看乙個多位數21905:

個位:它出現1的數為:1 ~ 21901,一共 2190 - 0 + 1 = 2191

十位:它出現1的數為:1x ~ 2181x (x 從0到9)一共:(218 - 0 + 1)*10 = 2190

百位:它出現1的數為:1xx ~ 211xx ,一共:(21 - 0 + 1)* 100 = 2200

千位:它出現1的數為:1*** ~ 11*** 和 21000 ~ 21905 ,那麼很明顯,這個情況就比較特殊了,為什麼呢?下面再說,我們先計數,一共:(1 - 0 + 1)*1000 + (905 - 0 + 1)= 2000 + 906 = 2906

萬位:它出現1的數為:1***x ~ 1***x,一共:10000

那麼我們求和:2191 + 2190 + 2200 + 2906 + 10000 = 19487(windows計算器得到)

和程式執行結果一樣:

然後我們說一下剛剛為什麼會有特殊的情況:

很明顯,如果當前位是0或者大於1時,那麼當前結果只與高位有關,如果是1的話,那麼還要把低位的也考慮進去。

以上就是這道題的思路了,數字dp?

**如下:

#include#include#include#includeusing namespace std;

int main()

else if(m==1)

else

k=k*10;

u=u/10;

} printf("%lld",sum);

return 0;

}

51nod 1009 數字1的數量

1009 數字1的數量 基準時間限制 1 秒 空間限制 131072 kb 分值 5 難度 1級演算法題 收藏 關注 給定乙個十進位制正整數n,寫下從1開始,到n的所有正數,計算出其中出現所有1的個數。例如 n 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。input ...

51 nod 1009 數字1的數量

1009 數字1的數量 基準時間限制 1 秒 空間限制 131072 kb 分值 5 難度 1級演算法題 收藏 關注 給定乙個十進位制正整數n,寫下從1開始,到n的所有正數,計算出其中出現所有1的個數。例如 n 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。input ...

51nod 1009 數字1的數量

1009 數字1的數量 基準時間限制 1 秒 空間限制 131072 kb 分值 5 難度 1級演算法題 給定乙個十進位制正整數n,寫下從1開始,到n的所有正數,計算出其中出現所有1的個數。例如 n 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。input 輸入n 1 ...