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
  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/rainydays/p/4298547.html
Copyright © 2011-2022 走看看