1. 程式人生 > >1042 數字0-9的數量(非數位dp解法)

1042 數字0-9的數量(非數位dp解法)

-c vertica ng-bind bit int 數字 變化 ica fas

1042 數字0-9的數量

給出一段區間a-b,統計這個區間內0-9出現的次數。 比如 10-19,1出現11次(10,11,12,13,14,15,16,17,18,19,其中11包括2個1),其余數字各出現1次。

輸入

兩個數a,b(1 <= a <= b <= 10^18)

輸出

輸出共10行,分別是0-9出現的次數

輸入樣例

10 19

輸出樣例

1
11
1
1
1
1
1
1
1
1


題意很明確,
其實只要能求的到b的就可以.
然後用val(b) - val(a-1)就能得出結果

我的思路是既然要求1到n的,那麽每次我只計算1到n的每個數的最後一位.
並且記錄最後一位的狀態變化.
比如求2018
那麽第一次就是2018/10 = 201 2018%10 = 8
那麽從0到9每個位上就能加201, 然後 1到8都加1
下一次就是201/10 = 20 201%10 = 1
那麽0到9每位加20*10 ,然後從1加9;
仔細看代碼就知道我的思路是什麽了.

每次都減掉最後一位數.
 1 #include <bits/stdc++.h>
 2 #define ll long long int
 3 using namespace std;
 4 ll a,b;
 5 ll an[10], bn[10];
6 void solve(ll x,ll xn[]){ 7 ll ans = 1; 8 ll cnt = 0; 9 while(x){ 10 ll aa = x/10; 11 for(int i = 0; i <= 9; i++){ 12 if(i == 0 && x%10 == 0) 13 xn[i] += (aa - 1)*ans; 14 else 15 xn[i] += aa*ans; 16
} 17 ll bb = x%10; 18 for(int i = 1; i < bb; i++){ 19 xn[i] += ans; 20 } 21 xn[bb] += cnt + 1; 22 cnt = cnt + (x%10 )*ans; 23 ans *= 10; 24 x /= 10; 25 } 26 } 27 int main(){ 28 scanf("%lld%lld", &a,&b); 29 solve(b, bn); 30 solve(a - 1, an); 31 for(int i = 0; i <= 9; ++i){ 32 printf("%lld\n",bn[i] - an[i]); 33 } 34 return 0; 35 }

1042 數字0-9的數量(非數位dp解法)