蓝桥杯2024省赛B组拔河问题:前缀和与双指针解法详解
一、问题背景
题目要求将n个人分成两组进行拔河比赛,每组必须连续排在一起,目标是让两组的总力量差值最小。这是典型的区间分割问题,需要高效计算所有可能的连续区间和。
二、核心算法思路
三、完整代码解析(带注释)
int main() { ios::sync_with_stdio(false); // 关闭同步提升IO速度 cin.tie(nullptr); int n; // 总人数 cin >> n; vector<int> a(n); // 存储每个人的力量值 for (int i = 0; i < n; ++i) cin >> a[i]; // 计算前缀和数组 vector<int> prefix(n + 1, 0); for (int i = 1; i <= n; ++i) prefix[i] = prefix[i - 1] + a[i - 1]; int min_diff = INT_MAX; // 初始化最小差值为最大整数 // 预处理所有可能的区间和及其边界 vector<pair<int, pair<int, int>>> sums; for (int l = 1; l <= n; ++l) { for (int r = l; r <= n; ++r) { // 存储区间和及对应的左右边界 sums.emplACe_back(prefix[r] - prefix[l-1], make_pair(r, l)); } } // 按区间和升序排序 sort(sums.begin(), sums.end()); // 双指针寻找最小差值 for (int i = 1; i < sums.size(); ++i) { // 确保区间不相交:前区间的右边界 < 后区间的左边界 if (sums[i-1].second.first < sums[i].second.second) { min_diff = min(min_diff, sums[i].first - sums[i-1].first); } } cout << min_diff << endl; return 0; }
四、关键算法点详解
前缀和数组:prefix数组可以在O(1)时间内计算任意区间和
区间枚举:双重循环枚举所有可能的连续区间
排序优化:将区间和排序后,相邻元素的差值更可能成为最小值
不相交检查:确保选取的两个区间不会重叠
五、实际应用场景
这种算法模式适用于:
资源分配的均衡问题
时间区间调度优化
数据分段统计分析
金融投资组合平衡
六、算法优化方向
原创内容 转载请注明出处