FZU 2113 Jason的特殊爱好

题意:

   给定区间[a,b],求将区间中所有数写在黑板上,要写的数字‘1’的次数。(1 <= a,b <= 10^8)

解法:

   将题转化成f(b+1) - f(a)的形式。普通的数位DP。

tag:数位DP

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-12-15 23:53
 4  * fILE nAME: dp-fzU-2113.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 
10 using namespace std;
11 
12 #define CLR(x) memset(x, 0, sizeof(x))
13 typedef long long int64;
14 int64 d[25][20];
15 int dit[25];
16 
17 int64 mypow(int64 p, int64 n)
18 {
19     int64 ret = 1;
20     while (n){
21         if (n & 1) ret *= p;
22         n >>= 1;
23         p *= p;
24     }
25     return ret;
26 }
27 
28 void d_init()
29 {
30     CLR (d);
31     d[1][1] = 1;
32     for (int i = 2; i < 25; ++ i){
33         d[i][1] = mypow(10, i-1);
34         for (int j = 0; j < 10; ++ j)
35             for (int k = 0; k < 10; ++ k)
36                 d[i][j] += d[i-1][k];
37     }
38 }
39 
40 int64 gao(int64 x)
41 {
42     int len = 0;
43     while (x){
44         dit[len++] = x % 10;
45         x /= 10;
46     }
47     dit[len] = 0;
48     
49     int64 ret = 0;
50     int flag = 0;
51     for (int i = len-1; i >= 0; -- i){
52         ret += dit[i] * mypow(10, i) * flag;
53         for (int j = 0; j < dit[i]; ++ j)
54             ret += d[i+1][j];
55         if (dit[i] == 1) ++ flag;
56     }
57     return ret;
58 }
59 
60 int main()
61 {
62     d_init();
63     int64 a, b;
64     while (cin >> a >> b)
65         cout << gao(b+1) - gao(a) << endl;
66     return 0;
67 }
View Code

 

posted @ 2013-12-16 00:54  Plumrain  阅读(217)  评论(0编辑  收藏  举报