CodeForces 55D Beautiful numbers

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces 55D Beautiful numbers相关的知识,希望对你有一定的参考价值。

题目链接:http://codeforces.com/problemset/problem/55/D

题意:一个数如果能够被她的每一个非0位整除,那么这个数就叫做Beautiful numbers。

给出l和r,问区间[l,r]中总共有多少个Beautiful numbers。

思路:

题意即这个数要能够被它的每个非0位的最小公倍数整除。

因为每一位最多就是1,2,3,4,5,6,7,8,9。也就是这个数最坏的情况要能够被1*2*3*4*5*6*7*8*9 = 2520整除。

设这个数为x,设x = 2520*t+y。设lcm为x每个非0位出现的数的最小公倍数。

那么可以知道2520 % lcm = 0。

所以x % lcm = x%2520%lcm。所以在记忆化搜索的时候只要保存当前数%2520的余数就可以了。

所以需要一个dp[cur][last][lcm] 大小有19*2520*2520要超内存,所以要把记录的lcm离散化一下。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 long long l, r;
 4 int num[22];
 5 int Hash[2550];
 6 long long dp[22][2530][50];
 7 void init()
 8 {
 9     memset(dp, -1, sizeof(dp));
10     int cnt = 0;
11     Hash[0] = 0;
12     for(int i = 1; i <= 2520; i++)
13     {
14         if(2520%i == 0) Hash[i] = ++cnt;
15     }
16 }
17 
18 int gcd(int a, int b)
19 {
20     if(a < b) return gcd(b, a);
21     if(b == 0) return a;
22     return gcd(b, a%b);
23 }
24 int getlcm(int a, int b)
25 {
26     return a/gcd(a,b)*b;
27 }
28 long long dfs(int cur, int last, int lcm, int limit)
29 {
30     if(cur < 0)
31     {
32         if(last % lcm == 0) return 1;
33         else return 0;
34     }
35     if(!limit && dp[cur][last][Hash[lcm]] != -1) return dp[cur][last][Hash[lcm]];
36     
37     long long ret = 0;
38     int up = limit?num[cur]:9;
39     for(int i = 0; i <= up; i++)
40     {
41         int temp = (last*10+i)%2520;
42         int nowlcm;
43         if(i != 0) nowlcm = getlcm(lcm, i);
44         else nowlcm = lcm;
45         ret += dfs(cur-1, temp, nowlcm, limit && i == up);
46     }
47     if(!limit) dp[cur][last][Hash[lcm]] = ret;
48     return ret;
49 }
50 long long slove(long long x)
51 {
52     int cnt = 0;
53     while(x)
54     {
55         num[cnt++] = x % 10;
56         x /= 10;
57     }
58     return dfs(cnt-1, 0, 1, 1);
59 }
60 int T;
61 int main() 
62 {
63     init();
64     scanf("%d", &T);
65     while(T--)
66     {
67       cin>>l>>r;
68       cout<<slove(r) - slove(l-1)<<endl;
69     }
70     return 0;
71 }

 

以上是关于CodeForces 55D Beautiful numbers的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 55D Beautiful numbers (数位DP)

CodeForces 55D Beautiful numbers

CodeForces 55D - Beautiful numbers - [数位DP+离散化]

codeforces55D Beautiful numbers

CodeForces - 55D - Beautiful numbers(数位DP,离散化)

CodeForces 55D Beautiful numbers