1 条题解

  • 0
    @ 2023-1-11 17:12:18
    #include <bits/stdc++.h>
    using namespace std;
    int L, R, N;
    int dp[15][105]; // 记忆化搜索 dp[pos][num]
    int d[15], dlen; // d[dlen]~d[1]
    // 做到了第 pos 位,要求数位和 %N 结果为 num,是否顶到了上限
    int dfs(int pos, int num, bool limit)
    {
        if (pos == 0)
        {
            if (num == 0)
                return 1;
            else
                return 0;
        }
        // 算过了没贴边的结果的话就直接返回
        if (!limit && dp[pos][num] != -1)
            return dp[pos][num];
        // 当前这一位的上限
        int up = limit ? d[pos] : 9;
        int sum = 0;                        // 记录方案数
        for (int now = 0; now <= up; now++) // 枚举当前这一位
        {
            // (模意义下)需求数位和为 num,当前这一位 now,需求剩下的位数数位和为 num-now
            int nxt = ((num - now) % N + N) % N;
            sum += dfs(pos - 1, nxt, limit && now == d[pos]);
        }
        // 如果前面没贴边,就记忆化一下
        if (!limit)
            dp[pos][num] = sum;
        return sum;
    }
    int cal(int x)
    {
        if (x == 0)
            return 1;
        dlen = 0;
        for (int i = x; i != 0; i /= 10)
            d[++dlen] = i % 10;
        return dfs(dlen, 0, true);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        while (cin >> L >> R >> N)
        {
            memset(dp, -1, sizeof(dp));
            cout << cal(R) - cal(L - 1) << "\n";
        }
        return 0;
    }
    
    • 1

    「一本通 5.3 练习 1」数字游戏(取模数)

    信息

    ID
    818
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    57
    已通过
    22
    上传者