UVa 11361 (计数 递推) Investigating Div-Sum Property

题意:

统计[a, b]中有多少个数字满足:自身是k的倍数,而且各个数字之和也是k的倍数。

分析:

详细分析见《训练之南》吧,=_=||

书上提出了一个模板的概念,有了模板我们就可以分块计算。

虽然书上定义f(x)表示不超过x的非负整数且满足条件的个数,但为了编码方便,代码中f(x)的含义为0~x-1中满足条件的个数。

这样最终所求为f(b+1) - f(a)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int MOD;
 5 int pow_ten[10];
 6 int f[11][90][90];
 7 
 8 inline int mod(int n)
 9 { return ((n % MOD) + MOD) % MOD; }
10 
11 int F(int d, int m1, int m2)
12 {
13     if(d == 0) return m1 == 0 && m2 == 0 ? 1 : 0;
14     int& ans = f[d][m1][m2];
15     if(ans >= 0) return ans;
16 
17     ans = 0;
18     for(int x = 0; x <= 9; x++)
19         ans += F(d-1, mod(m1-x), mod(m2-x*pow_ten[d-1]));
20     return ans;
21 }
22 
23 int sum(int n)
24 {
25     char digits[11];
26     sprintf(digits, "%d", n);
27     int nd = strlen(digits);
28 
29     int base = 0;
30     int sumd = 0;
31     int ans = 0;
32     for(int i = 0; i < nd; i++)
33     {
34         int na = nd - i - 1;
35         for(int d = 0; d < digits[i] - '0'; d++)
36             ans += F(na, mod(-sumd-d), mod(-base-d*pow_ten[na]));
37         sumd += digits[i] - '0';
38         base += (digits[i] - '0') * pow_ten[na];
39     }
40     return ans;
41 }
42 
43 int main()
44 {
45     //freopen("in.txt", "r", stdin);
46 
47     pow_ten[0] = 1;
48     for(int i = 1; i <= 9; i++) pow_ten[i] = pow_ten[i - 1] * 10;
49 
50     int T, a, b;
51     scanf("%d", &T);
52     while(T--)
53     {
54         scanf("%d%d%d", &a, &b, &MOD);
55         if(MOD > 82) { puts("0"); continue; }
56         memset(f, -1, sizeof(f));
57         printf("%d\n", sum(b+1) - sum(a));
58     }
59 
60     return 0;
61 }
代码君

 

posted @ 2015-03-04 16:49  AOQNRMGYXLMV  阅读(788)  评论(0编辑  收藏  举报