zoukankan      html  css  js  c++  java
  • HDU 4389 X mod f(x)

    题意:求[A,B]内有多少个数,满足x % f(x) == 0。


    解法:数位DP。转化为ans = solve(b) - solve(a - 1)。设dp[i][sum][mod][r]表示长度为i,各位和为sum,模mod余r的数的个数。

    当在数字后面新添加一位j时,则有dp[i + 1][sum + j][mod][(r * 10 + j) % mod] += dp[i][sum][mod][r]。

    当一个数比n小时,一定是因为从某一位开始出现了当前位的数字比n当前位数字小的情况,从高到低枚举这种情况出现的位数,枚举这位的数字,枚举所有数字的和,即模,满足等式(num + j * 10 ^ i + r) % mod == 0时即符合情况,num为前i位确定时的数值。

    for i len...1

    for j 0...digit[i]

    for mod 1...81

    for r 0...mod - 1

    if (当前已确定位数值 + j * 10 ^ i + r) % mod == 0

    ans += dp[i - 1][mod - 前i位和 - j][mod][r]


    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int dp[12][85][85][85] = {0};
    int f(int x)
    {
        if(x == 0) return 0;
        return f(x / 10) + x % 10;
    }
    void init()//初始化
    {
        for(int i = 0; i < 85; i++)
            dp[0][0][i][0] = 1;
        for(int i = 0; i < 9; i++)
            for(int j = 0; j < 85; j++)
                for(int k = 0; k < 85; k++)
                    for(int l = 0; l < k; l++)
                        for(int m = 0; m < 10 && m + j < 85; m++)
                            dp[i + 1][j + m][k][(l * 10 + m) % k] += dp[i][j][k][l];
    }
    int solve(int x)
    {
        int ans = 0;
        if(x && (x % f(x) == 0))
            ans++;
        int digit[15] = {0};
        int ten[15] = {0, 1, 0};
        for(int i = 2; i <= 10; i++)
            ten[i] = ten[i - 1] * 10;
        int len = 1;
        int tmp = x;
        while(tmp)
        {
            digit[len++] = tmp % 10;
            tmp /= 10;
        }
        int sum = 0;
        int num = 0;
        for(int i = len - 1; i >= 1; i--)//枚举位数
        {
            for(int j = 0; j < digit[i]; j++)
                for(int k = 1; k < 85; k++)
                    for(int l = 0; l < k; l++)
                        if((k >= (sum + j)) && ((num + j * ten[i] + l) % k == 0))
                            ans += dp[i - 1][k - sum - j][k][l];
            sum += digit[i];
            num += digit[i] * ten[i];
        }
        return ans;
    }
    int main()
    {
        init();
        int T;
        while(~scanf("%d", &T))
        {
            int cnt = 1;
            while(T--)
            {
                int a, b;
                scanf("%d%d", &a, &b);
                printf("Case %d: %d
    ", cnt++, solve(b) - solve(a - 1));
            }
        }
    }
    


  • 相关阅读:
    HBase with MapReduce (MultiTable Read)
    HBase with MapReduce (SummaryToFile)
    HBase with MapReduce (Summary)
    HBase with MapReduce (Read and Write)
    HBase with MapReduce (Only Read)
    Hbase中的BloomFilter(布隆过滤器)
    HBase的快照技术
    How To Use Hbase Bulk Loading
    Cloudera-Manager修改集群的IP
    Java中的HashSet和TreeSet
  • 原文地址:https://www.cnblogs.com/Apro/p/4303981.html
Copyright © 2011-2022 走看看