1 条题解
-
0
Guest MOD
-
2
看到题目的第一眼,这不模拟吗?看到数据范围,特别是 ,幻想破灭。
正解
别看 这么大,别着急,细心的你肯定发现,进行 次变异操作后,你会发现数字一定在 之中,所以你会发现,经过 次就必然会有重复数字,所以我们把循环节提取出来,用剩余变异次数 %= 循环节长度,再进行 ‘剩余变异次数’ 次遍历。 时间复杂度 O(m)
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n = 0, m, f[2000010], c[11], cnt; // f[i] 记录 i 在之前枚举中有没有出现,如果有,出现在那里 ll k; char s[100010]; int main() { //freopen("data10.in", "r", stdin); //freopen("data10.out", "w", stdout); scanf("%s%d%lld", s + 1, &m, &k); int len = strlen(s + 1); n = m; for (int i = 1; i <= len; i++) n += s[i] - '0'; // 高精度处理,并进行一次变异。 k--; f[n] = 1; memset(f, 0, sizeof(f)); for (int i = 2; ; i++) { cnt = 0; int t = n; while (t) { c[++cnt] = t % 10; t /= 10; } n = m; for (int i = 1; i <= cnt; i++) n += c[i]; // 进行一次变异 k--; if (f[n]) { k %= i - f[n]; // 找到循环节,循环节长度 = 当前 - 上一次,即 i - f[n] break; } else f[n] = i; // 处理 f } for (int i = 1; i <= k; i++) { // 进行 k 次遍历 cnt = 0; int t = n; while (t) { c[++cnt] = t % 10; t /= 10; } n = m; for (int i = 1; i <= cnt; i++) n += c[i]; } printf("%d\n", n); }
- 1
信息
- ID
- 1680
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 9
- 已通过
- 5
- 上传者