zoukankan      html  css  js  c++  java
  • Codeforces 55D Beautiful Number

    Codeforces 55D Beautiful Number

    a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits.

    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).

    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).

    Sample test(s)
    Input
    1
    1 9
    Output
    9
    Input
    1
    12 15
    Output
    2

    思路:

    1. 在mod中,有一个规律,X%a = X%(b*a)%a; <=> X%( lcm(1,2,...,9) = 2520)%lcm(d[i]) == 0;即可将数值直接降到2520以内;
    2. 同时一个mod后的数,还需要记录的就是lcm(d[i]),这样每次又计算出来的子结构就直接相加即可(指mod之后的数值以及lcm相同的数(这时就可以看成是一个数)),lcm总共只有48个,(2^3,3^2,5,7的组合 4*3*2*2);
    3. dp[i][j][k]: [i]: 高位为第i位,[j] : 在mod 2520之后的数值,[k]:记录下高位的lcm,由于直接来会MLE,所以离散化了(使用标号index[]);

    代码思路参考了:AC_Von

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,n) for(int (i)= 0;i < (n);i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    typedef long long ll;
    const int MOD = 2520;
    ll dp[21][2520][50];
    int d[21],index[MOD+5];
    void init()
    {
        for(int i = 1,tot = 0;i <= MOD;i++)
            if(MOD % i == 0)  index[i] = tot++;
        MS1(dp);
    }
    int lcm(int a,int b)
    {
        return a/__gcd(a,b)*b;
    }
    ll dfs(int pos,int prev,int prelcm,int edge)
    {
        if(pos == -1) return prev % prelcm?0:1; // ***
        ll ans = dp[pos][prev][index[prelcm]];
        if( !edge && ~ans) return ans;
        ans = 0;
        int e = edge ? d[pos]:9;
        for(int i = 0;i <= e;i++){
            int nowlcm = i ? lcm(prelcm,i) : prelcm;
            int nowv = (prev * 10 + i)%MOD;
            ans += dfs(pos - 1,nowv,nowlcm,edge && i == e);
        }
        if(!edge) dp[pos][prev][index[prelcm]] = ans;
        return ans;
    }
    ll query(ll n)
    {
        MS0(d);int tot = 0;
        while(n){
            d[tot++] = n%10;
            n /= 10;
        }
        return dfs(tot - 1,0,1,1);
    }
    int main()
    {
        init();
        int T;
        cin>>T;
        while(T--){
            ll l,r;
            scanf("%I64d%I64d",&l,&r);
            printf("%I64d
    ",query(r) - query(l-1));
        }
    }
    View Code
  • 相关阅读:
    vim复制
    嵌入式Linux学习(二)
    (Java实现) 洛谷 P1042 乒乓球
    (Java实现) 洛谷 P1042 乒乓球
    (Java实现) 洛谷 P1071 潜伏者
    (Java实现) 洛谷 P1071 潜伏者
    (Java实现) 洛谷 P1025 数的划分
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
  • 原文地址:https://www.cnblogs.com/hxer/p/5169877.html
Copyright © 2011-2022 走看看