安全密码
#include <bits/stdc++.h>
using namespace std;
#define ll long long // 定义long long类型简写
int main() {
string s; // 存储输入的密码字符串
cin >> s; // 读取输入
ll ans = 0; // 记录总操作次数
int cntB = 0; // 统计B操作的累积次数(模10意义下)
// 从字符串末尾向前遍历(逆向处理)
for (int i = s.size()-1; i >= 0; i--) {
int t = s[i] - '0'; // 将当前字符转换为数字
// 调整当前数字:考虑之前所有B操作的影响
// +10是为了避免负数,%10确保在0-9范围内
t = (t - cntB % 10 + 10) % 10;
// 处理第一个字符(最左边的字符)
if (i == 0) {
ans += t; // 第一个字符只能通过t次B操作得到
} else {
// 对于其他位置的字符
if (t == 0) {
ans++; // 0只需1次A操作(追加0)
} else {
// 非0字符需要:t次B操作+1次A操作
ans += t + 1;
cntB += t; // 累计B操作次数
}
}
}
// 输出总操作次数(+1是因为初始空字符串需要一次操作才能开始)
cout << ans;
return 0;
}
解题思路:
-
逆向思维:从字符串末尾向前处理,这样可以更好地跟踪B操作的影响。
-
关键观察:
- 每个B操作会影响字符串中的所有数字
- A操作只在字符串末尾添加0
- 最左边的字符只能通过B操作得到
-
操作影响计算:
- 对于每个数字,需要减去之前所有B操作的影响(模10)
- 如果调整后的数字是0,说明只需要1次A操作
- 如果是其他数字,需要相应次数的B操作和1次A操作
-
累积效应:
- 使用cntB记录B操作的总次数
- 每次B操作的影响会传递到前面处理的字符
-
边界情况:
- 第一个字符特殊处理(只能通过B操作)
- 空字符串需要至少一次操作才能开始
为什么这样计算:
- 逆向处理:因为B操作会影响所有前面的字符,从后往前可以更容易计算每个字符需要的原始值
- 模运算:B操作的效果是循环的(0→1→...→9→0),所以用模10处理
- 操作计数:每个字符的生成要么通过A+B组合,要么直接通过B(对第一个字符)
这个算法的时间复杂度是O(n),其中n是字符串长度,非常高效,适合处理最大5×10^5长度的输入。

浙公网安备 33010602011771号