题解
2026-02-26 13:02:34
发布于:浙江
3阅读
0回复
0点赞
题目解析
- 输入输出:第一行输入整数 表示测试用例组数。每组数据包含:一行整数 表示序列长度,一行 个正整数表示序列。对每组数据输出
Yes表示存在位置 ()使得前 个元素之和等于剩余元素之和,否则输出No。 - 数据范围:,。多组数据总规模适中,单个序列长度不超过 。
- 复杂度要求:每组数据需要 时间处理,总时间复杂度 ,符合 1s 限制;空间复杂度 存储序列。
- 算法知识点:
前缀和、后缀和、双指针、枚举
思路解析
- 总和初始化:首先遍历序列计算所有元素的总和,记为
right_sum,表示当前分割点右侧所有元素的和(初始时右侧为整个序列)。 - 同步维护左右和:从左到右遍历序列(分割点 从 到 ),每次将当前元素 从
right_sum中减去(右侧不再包含该元素),并加入left_sum(左侧包含该元素)。这样left_sum始终表示前 个元素的和,right_sum表示第 到第 个元素的和。 - 平衡判定:在每一步更新后,检查
left_sum与right_sum是否相等。若相等,说明找到一个合法分割点,立即输出Yes并结束当前测试用例。 - 未找到处理:若遍历完所有可能的分割点( 从 到 )均未发现相等的情况,输出
No。 - 精度处理:使用
long long存储和值,防止多个 级别数值累加导致int溢出(虽然题目范围内 在int范围内,但这是良好的 defensive programming 习惯)。
完整代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10; // 数组大小,大于最大数据范围
int arr[MAXN];
void solve() {
int n;
// 多组数据,清空数组避免干扰
memset(arr, 0, sizeof(arr));
cin >> n;
long long right_sum = 0, left_sum = 0; // 分别记录右侧和、左侧和
// 读入序列并计算总和(作为初始的右侧和)
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
right_sum += arr[i];
}
// 遍历所有可能的分割位置 i(1 到 n-1)
for (int i = 1; i < n; ++i) {
right_sum -= arr[i]; // 右侧不再包含 arr[i]
left_sum += arr[i]; // 左侧加入 arr[i]
// 关键判断:左右两部分和相等
if (left_sum == right_sum) {
cout << "Yes" << endl;
return; // 找到立即返回,无需继续检查
}
}
cout << "No" << endl;
}
int main() {
int t;
cin >> t;
// 循环处理 t 组测试用例
while(t--) solve();
return 0;
}
这里空空如也

有帮助,赞一个