题目链接
题意:给定一个数,定义一个操作:把每一位+1后插入原位置,即'191'
一次操作后变为'2102'
。问
k
(
k
≤
2
∗
1
0
5
)
k(k\le 2*10^5)
k(k≤2∗105)次操作后结果有多少位.共有
t
(
t
≤
2
∗
1
0
5
)
t(t\le 2*10^5)
t(t≤2∗105)次询问。
思路:如果对于每次操作都模拟一次的话,肯定会超时。此时我们想到预处理,很容易注意到对于给出的数,每一位的操作实际上是独立的,同时考虑到,对于某个位上的数 (假设为
x
x
x)而言,对整个串进行
k
k
k次操作实际上等同于对其进行
x
+
k
x+k
x+k次操作,故只需预处理对
0
0
0操作
0
0
0~
m
a
x
(
k
)
+
9
max(k)+9
max(k)+9次的结果即可。预处理可以使用dp,代码中
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示第i次操作后数位
j
j
j的数量,转移如下:
dp[i][0] = dp[i - 1][9];
dp[i][1] = (dp[i - 1][9] + dp[i - 1][0]) % mod;
for (int j = 2; j < 10; j++) dp[i][j] = dp[i - 1][j - 1];
AC代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;
/***************main****************/
ll T = 1;
ll m, n;
ll dp[maxn + 10][10];
queue<ll> pos;
int main() {
T = read();
dp[0][0] = 1;
for (int i = 1; i <= 2e5 + 10; i++) {
dp[i][0] = dp[i - 1][9];
dp[i][1] = (dp[i - 1][9] + dp[i - 1][0]) % mod;
for (int j = 2; j < 10; j++) dp[i][j] = dp[i - 1][j - 1];
}
while (T--) {
ll x = read(), k = read(), ans = 0;
while (x) {
ll tmp = 0;
for (int i = 0; i < 10; i++) tmp = (dp[k + x % 10][i] + tmp) % mod;//统计长度
ans = (ans + tmp) % mod;
x /= 10;
}
cout << ans << endl;
}
return 0;
}