C++求解删除字符最大化模值问题代码报错求排查优化
现有代码错误点
- 整数溢出问题:
stoi仅能转换长度不超过10位的数字字符串,若输入的数字字符串长度超过int甚至long long的存储上限,直接转换会触发溢出崩溃,是运行错误的核心原因。 - 逻辑错误:题目要求必须删除1个字符,你在判断k的位数等于字符串长度时,直接输出原字符串转整数的结果,没有执行删除操作,完全不符合题意,导致答案错误。
- 时间复杂度过高:双重循环生成删除每个字符后的新字符串,时间复杂度为O(m²),当m取值较大时会直接超时,无法通过大测试用例。
最优解法思路
采用前缀模+后缀模+预处理10的幂次模的方法,全程用模运算避免溢出,时间复杂度降至O(m):
- 预处理
pow10数组:pow10[i]表示10的i次方模k的结果 - 预处理前缀模数组
pre:pre[i]表示字符串前i个字符(s[0]到s[i-1])组成的数模k的结果,递推公式为pre[i] = (pre[i-1] * 10 + (s[i-1] - '0')) % k - 预处理后缀模数组
suf:suf[i]表示字符串从第i个字符到末尾(s[i]到s[m-1])组成的数模k的结果,递推公式为suf[i] = ((s[i] - '0') * pow10[m - i - 1] + suf[i+1]) % k - 遍历每个要删除的位置i,当前删除后的模值为
(pre[i] * pow10[m - i - 1] + suf[i+1]) % k,记录最大值即可
优化后代码
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int m, k; cin >> m >> k; string s; cin >> s; vector<long long> pow10(m); pow10[0] = 1 % k; for (int i = 1; i < m; i++) { pow10[i] = (pow10[i-1] * 10) % k; } vector<long long> pre(m+1, 0); for (int i = 0; i < m; i++) { pre[i+1] = (pre[i] * 10 + (s[i] - '0')) % k; } vector<long long> suf(m+1, 0); for (int i = m-1; i >= 0; i--) { suf[i] = ((1LL * (s[i] - '0') * pow10[m - i - 1]) + suf[i+1]) % k; } int max_mod = 0; for (int i = 0; i < m; i++) { long long current = (pre[i] * pow10[m - i - 1] + suf[i+1]) % k; if (current > max_mod) { max_mod = current; } } cout << max_mod << '\n'; } return 0; }
内容的提问来源于stack exchange,提问作者YASH PRATAP SINGH
相关产品推荐
相关产品推荐

