数字游戏Ⅱ

https://www.acwing.com/problem/content/1086/

\(cpp负数的取模:(-a)\%b==-(a\%b)\)

状态表示
  • \(f[i][j][x]:有i位最高位位j且所有位之和对p取模的值为x\)
状态计算
  • \(f[i][j][x]+=f[i-1][k][mod(x-j)]\)
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define pb push_back
#define PII pair<int, int>
#define fi first
#define se second
#define inf 0x3f3f3f3f
const int N = 15;
int f[N][10][110];
int p;

int mod(int x) {
    return (x % p + p) % p;
}

void init() {
    for (int i = 0; i <= 9; ++i) f[1][i][i % p] = 1;
    for (int i = 2; i < N; ++i)
        for (int j = 0; j <= 9; ++j)
            for (int k = 0; k <= 9; ++k)
                for (int x = 0; x < p; ++x)
                    f[i][j][x] += f[i - 1][k][mod(x - j)];
}

int dp(int n) {
    if (!n) return 1;
    vector<int> num;
    while (n) num.pb(n % 10), n /= 10;
    n = num.size();
    int res = 0, last = 0;
    for (int i = n - 1; i >= 0; --i) {
        int x = num[i];
        for (int j = 0; j < x; ++j) res += f[i + 1][j][mod(-last)];
        last += x;
        if (!i && last % p == 0) ++res;
    }
    return res;
}

int main() {
    IO;
    int l, r;
    while (cin >> l >> r >> p) {
        memset(f, 0, sizeof f);
        init();
        cout << dp(r) - dp(l - 1) << '\n';
    }
    return 0;
}

posted @ 2021-02-02 20:34  phr2000  阅读(48)  评论(0编辑  收藏  举报