[51nod1009]數字1的數量
解題關鍵:數位dp,對每一位進行考慮,通過過程得出每一位上1出現的次數
1位數的情況:
在解法二中已經分析過,大於等於1的時候,有1個,小於1就沒有。
2位數的情況:
N=13,個位數出現的1的次數為2,分別為1和11,十位數出現1的次數為4,分別為10,11,12,13,所以f(N) = 2+4。
N=23,個位數出現的1的次數為3,分別為1,11,21,十位數出現1的次數為10,分別為10~19,f(N)=3+10。
由此我們發現,個位數出現1的次數不僅和個位數有關,和十位數也有關,如果個位數大於等於1,則個位數出現1的次數為十位數的數字加1;如果個位數為0,個位數出現1的次數等於十位數數字。而十位數上出現1的次數也不僅和十位數相關,也和個位數相關:如果十位數字等於1,則十位數上出現1的次數為個位數的數字加1,假如十位數大於1,則十位數上出現1的次數為10。
3位數的情況:
N=123
個位出現1的個數為13:1,11,21,…,91,101,111,121
十位出現1的個數為20:10~19,110~119
百位出現1的個數為24:100~123
我們可以繼續分析4位數,5位數,推導出下面一般情況:
假設N,我們要計算百位上出現1的次數,將由三部分決定:百位上的數字,百位以上的數字,百位一下的數字。
如果百位上的數字為0,則百位上出現1的次數僅由更高位決定,比如12013,百位出現1的情況為100~199,1100~1199,2100~2199,…,11100~11199,共1200個。等於更高位數字乘以當前位數,即12 * 100。
如果百位上的數字大於1,則百位上出現1的次數僅由更高位決定,比如12213,百位出現1的情況為100~199,1100~1199,2100~2199,…,11100~11199,12100~12199共1300個。等於更高位數字加1乘以當前位數,即(12 + 1)*100。
如果百位上的數字為1,則百位上出現1的次數不僅受更高位影響,還受低位影響。例如12113,受高位影響出現1的情況:100~199,1100~1199,2100~2199,…,11100~11199,共1200個,但它還受低位影響,出現1的情況是12100~12113,共114個,等於低位數字113+1。
1#include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int solve(int n){ 5 int cnt=0,i=1,be,af,cur; 6 while(n/i){ 7 be=n/(i*10); 8 af=n-n/i*i; 9 cur=n/i%10; 10 11 if(cur>1) cnt+=(be+1)*i; 12 else if(cur<1) cnt+=be*i; 13 else cnt+=be*i+1+af; 14 i*=10; 15 } 16 return cnt; 17 } 18 int main(){ 19 int n; 20 cin>>n; 21 int ans=solve(n); 22 cout<<ans<<endl; 23 return 0; 24 }
[51nod1009]數字1的數量