2022.10.26每日一题

Daimayuan Online Judge-加一

题目描述

给定一个整数 \(n\)。你需要对它做 \(m\) 次操作。在一次操作中,你要将这个数的每一位 \(d\) 替换成 \(d+1\)。比如,\(1912\) 在进行一次操作后将变成 \(21023\)
请求出整数 \(n\) 进行了 \(m\) 次操作后的长度。答案可能很大,输出对 \(10^9+7\) 取模后的结果。

输入格式

第一行一个整数 \(t\),表示测试单元的个数。
接下来 \(t\) 行,每行有两个整数 \(n\)\(m\),表示最初的数字和进行多少次操作。

输出格式

对于每个测试单元输出最终数字的长度,答案对 \(10^9+7\) 取模。

样例输入
5
1912 1
5 6
999 1
88 2
12 100
样例输出
5
2
6
4
2115
数据范围

所有数据保证 \(1≤t≤2*105,1≤n≤10^9,1≤m≤2*10^5\)

解题思路
  • 状态表示 \(f[i][j]\):数 \(j\) 经过 \(i\)\(+1\)操作后的数的位数
  • 状态计算/集合划分:对于 \(f[i][j-1],j\in[1,9]=f[i-1][j]\),而 \(f[i][9]=f[i-1][0]+f[i-1][1]\),因为 \(9+1=10\)
C++代码
#include <bits/stdc++.h>
using namespace std;
const int N = 200010, mod = 1e9 + 7;
typedef long long LL;

int t;
LL f[N][10]; // f[i][j] 表示该位为 j 的数经过 i 次操作的数的位数

int main()
{
    for(int i = 0; i < 10; i ++)
        f[0][i] = 1;
    for(int i = 1; i <= N; i ++)
    {
        for(int j = 1; j <= 9; j ++)
            f[i][j - 1] = f[i - 1][j];
        f[i][9] = (f[i - 1][0] + f[i - 1][1]) % mod;
    }
    scanf("%d", &t);
    while(t --)
    {
        char str[15];
        int m;
        scanf("%s%d", str, &m);
        LL res = 0;
        for(int i = 0; str[i]; i ++)
            res = (res + f[m][str[i] - '0']) % mod;
        printf("%lld\n", res);
    }
    return 0;
}
posted @ 2022-10-27 10:56  Cocoicobird  阅读(43)  评论(0)    收藏  举报