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

    基本的数位DP,注意记录那些状态可以用最小的空间判断出整除性。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define D(x) 
    
    const int MAX_DIGIT_NUM = 20;
    
    int f[MAX_DIGIT_NUM];
    long long memoize[MAX_DIGIT_NUM][5][7][8][9][1 << 8];
    bool contain[10];
    
    int to_digits(long long n)
    {
        int ret = 0;
        while (n > 0)
        {
            f[ret++] = n % 10;
            n /= 10;
        }
        return ret;
    }
    
    bool check(int r5, int r7, int r8, int r9, int status)
    {
        D(printf("%d%d%d%d %d
    ", r5, r7, r8, r9, status));
        memset(contain, 0, sizeof(contain));
        int i = 2;
        while (status)
        {
            contain[i++] = status & 1;
            status >>= 1;
        }
        if (contain[2] && r8 % 2)
        {
            return false;
        }
        if (contain[3] && r9 % 3)
        {
            return false;
        }
        if (contain[4] && r8 % 4)
        {
            return false;
        }
        if (contain[5] && r5 % 5)
        {
            return false;
        }
        if (contain[6] && (r8 % 2 || r9 % 3))
        {
            return false;
        }
        if (contain[7] && r7)
        {
            return false;
        }
        if (contain[8] && r8 % 8)
        {
            return false;
        }
        if (contain[9] && r9 % 9)
        {
            return false;
        }
        D(puts("***"));
        return true;
    }
    
    long long dfs(int digit, bool less, int r5, int r7, int r8, int r9, int status)
    {
        D(printf("%d
    ", status));
        if (digit < 0)
        {
            return check(r5, r7, r8, r9, status);
        }
        if (less && memoize[digit][r5][r7][r8][r9][status] != -1)
        {
            return memoize[digit][r5][r7][r8][r9][status];
        }
        int limit = less ? 9 : f[digit];
        long long ret = 0;
        for (int i = 0; i <= limit; i++)
        {
            int next_status = i < 2 ? status : status | (1 << (i - 2));
            ret += dfs(digit - 1, less || i < f[digit], i % 5, (r7 * 10 + i) % 7, (r8 * 10 + i) % 8, (r9 * 10 + i) % 9, next_status);
        }
        if (less) 
        {
            memoize[digit][r5][r7][r8][r9][status] = ret;
        }
        return ret;
    }
    
    long long work(long long n)
    {
        if (n == 0)
        {
            return 1;
        }
        int len = to_digits(n);
        return dfs(len - 1, false, 0, 0, 0, 0, 0);
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        memset(memoize, -1, sizeof(memoize));
        while (t--)
        {
            long long a, b;
            scanf("%I64d%I64d", &a, &b);
            printf("%I64d
    ", work(b) - work(a - 1));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java定义类 对象,引用,指针
    java数组 数组工具类Arrays
    java 流程执行 循环 foreach循环
    java注释 命名 数据类型 基本类型转换 位运算符 逻辑运算符 三目运算符
    maven 学习1 -安装maven 并执行编译命令
    Lucene工作原理(转)
    nginx&tomcat实现负载均衡
    nginx安装(centos-7下安装nginx-1.8.1)
    spring中bean的作用域
    Spring管理事务配置的五种方式
  • 原文地址:https://www.cnblogs.com/rainydays/p/4298547.html
Copyright © 2011-2022 走看看