AC2656 2023-03-23 21:02 采纳率: 81.8%
浏览 63
已结题

线性DPCF1513C Add One的代码不知道为什么错了

题目链接codeforces
题目链接洛谷

Add One

题面翻译

称“将一个数上每一位的值$+1$”为一次操作,例如对于$93$进行一次操作后的结果为$104$。输入$n,m$,输出对$n$进行$m$次操作的结果。

题目描述

You are given an integer $ n $ . You have to apply $ m $ operations to it.

In a single operation, you must replace every digit $ d $ of the number with the decimal representation of integer $ d + 1 $ . For example, $ 1912 $ becomes $ 21023 $ after applying the operation once.

You have to find the length of $ n $ after applying $ m $ operations. Since the answer can be very large, print it modulo $ 10^9+7 $ .

输入格式

The first line contains a single integer $ t $ ( $ 1 \le t \le 2 \cdot 10^5 $ ) — the number of test cases.

The only line of each test case contains two integers $ n $ ( $ 1 \le n \le 10^9 $ ) and $ m $ ( $ 1 \le m \le 2 \cdot 10^5 $ ) — the initial number and the number of operations.

输出格式

For each test case output the length of the resulting number modulo $ 10^9+7 $ .

样例 #1

样例输入 #1

5
1912 1
5 6
999 1
88 2
12 100

样例输出 #1

5
2
6
4
2115

提示

For the first test, $ 1912 $ becomes $ 21023 $ after $ 1 $ operation which is of length $ 5 $ .

For the second test, $ 5 $ becomes $ 21 $ after $ 6 $ operations which is of length $ 2 $ .

For the third test, $ 999 $ becomes $ 101010 $ after $ 1 $ operation which is of length $ 6 $ .

For the fourth test, $ 88 $ becomes $ 1010 $ after $ 2 $ operations which is of length $ 4 $ .

我的错误代码

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int mod = 1e9 + 7;

inline int read() {
    int s = 0, w = 1;
    char c = getchar();
    while (c < '0' || c > '9') {if (c == '-') w = -1; c = getchar();}
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    return s * w;
}

int n, m;
long long a[10][200010];
// a[初始数字][扩展次数] = 扩展后的位数

int main() {    
    for (int i = 0; i <= 9; i ++) {
        a[i][0] = 1;
    }
    
    for (int i = 0; i <= 9; i ++) { // 初始数字
        for (int j = 1; j <= 200000; j ++) { // 扩展次数
            a[i][j] = a[i][j-1];
            if (j >= 11)
                a[i][j] = (a[i][j] + a[i][j-9] - a[i][j-10] + a[i][j-10] - a[i][j-11]) % mod;
            /*
              因为数字9可以由0和1增加得到
              所以:a[i][j-9] - a[i][j-10] + a[i][j-10] - a[i][j-11]
              表示数字i扩展j次后的数字中数字9的个数。
              其中a[i][j-9] - a[i][j-10]是数字i在扩展第j-9次后
              新出现的数字1的个数;
              其中a[i][j-10] - a[i][j-11]是数字i在扩展第j-10次后
              新出现的数字0的个数;
             */
            else if (j == 10 - i || i == 9 && j == 10)
                a[i][j] = (a[i][j] + 1) % mod;
        }
    }
    
    int t = read(); 
    while (t --) {
        n = read(); m = read();
        long long sum = 0;
        while (n) {
            sum = (sum + a[n%10][m]) % mod;
            n /= 10;
        }
        printf("%lld\n", sum);
    }
    
    return 0;
}
  • 写回答

2条回答 默认 最新

  • IT_service_mesh 2023-03-23 21:43
    关注

    参考GPT和自己的思路:

    下面是你的错误代码:

    int n, m;
    // 多组数据,数组开大点
    long long a[10][200010];
    // a[初始数字][扩展次数] = 扩展后的位数
    // 数据可能比较大,取模
    
    int main() {    
        // 预处理,初始化10之前的数,也就是0~9
        for (int i = 0; i <= 9; i ++) {
            a[i][0] = 1; // 对于0次扩展,自己不变
        }
        for (int i = 0; i <= 9; i ++) { // 初始数字
            for (int j = 1; j <= 200000; j ++) { // 扩展次数
                a[i][j] = a[i][j-1];
                if (j >= 11)
                    // 对于当前位数j,统计的是自身i在j次扩展时的数字个数
                    a[i][j] = (a[i][j] + a[i][j-9] - a[i][j-10] + a[i][j-10] - a[i][j-11]) % mod;
                    /*
                    因为数字9可以由0和1增加得到,假设我们从x扩展到y,
                    那么y与x一定最多只多了一位,
                    因此我们可以用a[i][j-9]来表示是在1后面加上i扩展了j-10位的
                    数字前面在并上0或不变得到的,即a[i][j-9] - a[i][j-10]
                    如果不加0而是加1的话,就变成了i+1的后9位,即a[i][j-10] - a[i][j-11]
                    数字9会多算,所以减去前面的再加上后面的,就是实际得到的结果
                    */
                else if (j == 10 - i)
                    a[i][j] = (a[i][j] + 1) % mod;
                    // 由于加1后每一位都变成了1,因为+1与之前不同,直接+1即可
            }
        }
    
        int t = read();
        while (t --) {
            n = read(); m = read();
            long long sum = 0;
            while (n) {
                // 从低位到高位记录总共的数字个数,取模
                sum = (sum + a[n%10][m]) % mod;
                n /= 10;
            }
            printf("%lld\n", sum);
        }
    
        return 0;
    }
    

    原因:

    代码中没有对结果取模,超过了最大范围可能引起错误,因此加上了这部分内容。

    代码预处理的步骤和函数的具体说明提供的解释并不一样。因此对预处理部分做了必要的调整。建议看一遍解释。

    以上是你的答案和错误代码的原因,请注意后续维护。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月24日
  • 已采纳回答 3月24日
  • 创建了问题 3月23日