zoukankan      html  css  js  c++  java
  • U Beautiful numbers 数位DP

    题目

    Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.

    Input

    The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).

    Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).

    Output

    Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).

    Examples

    Input

    1
    1 9

    Output

    9

    Input

    1
    12 15

    Output

    2

    题解

    %liuchanglc的博客

    解题思路

    这道题数据范围很大,暴力肯定会TLE
    那我们就用一种高级的暴力——数位DP
    顾名思义,就是在数位上做DP
    如果不懂,在看看liuchanglc大佬的博客

    代码

    #include <cstdio>
    #include <cstring>
    #define int long long 
    using namespace std;
    int f[20][3000][60], a[60], m[3000], t;
    int gcd(int x, int y) {
        return y ? gcd(y, x % y) : x;
    }
    int dp(int n, int s, int x, int g) {
        //g记录前一位能不能达到最大值
        if (n < 0) return (s % x) ? 0 : 1;
        if (!g && f[n][s][m[x]] != -1)
            return f[n][s][m[x]];
        int mn = 9, ms = 0;
        if (g) mn = a[n];
        for(int i = 0; i <= mn; i++)
            ms += dp(n - 1, (s *10 + i) % 2520, i ? i * x / gcd(i, x) : x, g && i == mn);
        if (!g) f[n][s][m[x]] = ms;
        return ms;
    }
    int getnum(int x) {
        int tot = 0;
        while (x) a[tot++] = x % 10, x /= 10;
        //a数组记录数字的每一位
        return dp(tot - 1, 0, 1, 1);
    }
    signed main() {
        scanf("%lld", &t);
        for(int i = 1, j = 0; i <= 2520; i++)
            if (2520 % i == 0) m[i] = j++;
        //m数组相当于离散化,压缩f数组的空间
        memset(f, -1, sizeof(f));
        while (t--) {
            int x, y;
            scanf("%lld%lld", &x, &y);
            printf("%lld
    ", getnum(y) - getnum(x - 1));
            //查分思想
        }
        return 0;
    }
    
  • 相关阅读:
    叩开抽象的大门(2)——依赖于抽象
    威老迷宫探险第二季如何更面向对象
    更佳的封装之路面向对象的封装思想
    威老的迷宫探险
    重用,我要重用!!!
    威老出国记,什么是引用,别名。
    叩开抽象的大门(1)——抽象类、接口
    maven常用命令
    大公司喜欢问的问题
    java 发送http请求
  • 原文地址:https://www.cnblogs.com/Z8875/p/12726074.html
Copyright © 2011-2022 走看看