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 }
代码君

 

你可能感兴趣的:(property)