zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Spring cloud实现服务注册及发现
    使用spring cloud实现分布式配置管理
    spring cloud教程之使用spring boot创建一个应用
    7天学会spring cloud教程
    微服务开发的12项要素
    一句话概括下spring框架及spring cloud框架主要组件
    翻译-服务注册与发现
    翻译-微服务API Gateway
    微服务分布式事务的一些思考
    解决不能正常访问workerman的问题
  • 原文地址:https://www.cnblogs.com/titicia/p/5234784.html
Copyright © 2011-2022 走看看