51nod 1009 數字1的數量 (統計1的總個數,好題)
輸入N(1 <= N <= 10^9)Output
輸出包含1的個數Input示例
12Output示例
5
思路,根據n的位數,我們統計一下個位、十位、百位,每一位上1所作出的貢獻,然後根據每個位是大於1,小於1,還是等於1,進行分類討論!!!
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int sum[20]; int getlen(int n) { int num=0; while(n) { n=n/10; num++; } return num; } int main() { int n,i,j,t1,t2,len,ans; cin>>n; len=getlen(n); sum[1]=n/10; if(n%10>=1) sum[1]++; for(i=2,t1=10,t2=100;i<=len;i++,t1=t1*10,t2=t2*10) { if(n/t1%10>1) { sum[i]=n/t2+1; sum[i]=sum[i]*t1; } else if(n/t1%10==1) { sum[i]=n/t2; sum[i]=sum[i]*t1+n%t1+1; } else { sum[i]=n/t2; sum[i]=sum[i]*t1; } } ans=0; for(i=1;i<=len;i++) ans+=sum[i]; cout<<ans<<endl; return 0; }
下面是從別人那盜來來的題解,跟我的思路差不多,方便以後複習用:
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。