【二分查找 前缀和】P10429 [蓝桥杯 2024 省 B] 拔河|普及+

本文涉及的基础知识点

本博文代码打包下载
C++二分查找
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

蓝桥杯 2024 省 B 拔河

题目描述

小明是学校里的一名老师,他带的班级共有 n n n 名同学,第 i i i 名同学力量值为 a i a_i ai。在闲暇之余,小明决定在班级里组织一场拔河比赛。

为了保证比赛的双方实力尽可能相近,需要在这 n n n 名同学中挑选出两个队伍,队伍内的同学编号连续 { a l 1 , a l 1 + 1 , ... , a r 1 − 1 , a r 1 } \{{a_{l_1}}, a_{l_1 + 1}, \dots, a_{r_1 - 1}, a_{r_1}\} {al1,al1+1,...,ar1−1,ar1} 和 { a l 2 , a l 2 + 1 , ... , a r 2 − 1 , a r 2 } \{{a_{l_2}}, a_{l_2 + 1}, \dots, a_{r_2 - 1}, a_{r_2}\} {al2,al2+1,...,ar2−1,ar2},其中 l 1 ≤ r 1 < l 2 ≤ r 2 l_1 \le r_1<l_2 \le r_2 l1≤r1<l2≤r2。

两个队伍的人数不必相同,但是需要让队伍内的同学们的力量值之和尽可能相近。请计算出力量值之和差距最小的挑选队伍的方式。

输入格式

输入共两行。

第一行为一个正整数 n n n。

第二行为 n n n 个正整数 a 1 , a 2 , ... a n a_1, a_2, \dots a_n a1,a2,...an。

输出格式

输出共一行,一个非负整数,表示两个队伍力量值之和的最小差距。

样例 #1

样例输入 #1

复制代码
5
10 9 8 12 14

样例输出 #1

复制代码
1

提示

样例 1 解释

其中一种最优选择方式:

队伍 1: { a 1 , a 2 , a 3 } \{a_1, a_2, a_3\} {a1,a2,a3},队伍 2: { a 4 , a 5 } \{a_4, a_5\} {a4,a5},力量值和分别为 10 + 9 + 8 = 27 10 + 9 + 8 = 27 10+9+8=27, 12 + 14 = 26 12 + 14 = 26 12+14=26,差距为 ∣ 27 − 26 ∣ = 1 |27 − 26| = 1 ∣27−26∣=1。

数据规模与约定

  • 对 20 % 20\% 20% 的数据, n ≤ 50 n \leq 50 n≤50。
  • 对全部的测试数据,保证 1 ≤ n ≤ 1 0 3 1 \leq n \leq 10^3 1≤n≤103, 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1≤ai≤109。

二分查找 前缀和

preSum记录前缀和。

两层循环,分别枚举l2,r2。

在有序集合s中寻找,最接近preSumr2+1-preSuml2的数。

在循环l2的结束:

将preSuml2+1-perSumi 加到s中。i ∈ \in ∈0,l2

代码

核心代码

cpp 复制代码
#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>
#include<list>

#include <bitset>
using namespace std;

template<class T1, class T2>
std::istream& operator >> (std::istream& in, pair<T1, T2>& pr) {
	in >> pr.first >> pr.second;
	return in;
}

template<class T1, class T2, class T3 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3>& t) {
	in >> get<0>(t) >> get<1>(t) >> get<2>(t) ;
	return in;
}

template<class T1, class T2, class T3, class T4 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4>& t) {
	in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
	return in;
}

template<class T = int>
vector<T> Read() {
	int n;
	scanf("%d", &n);
	vector<T> ret(n);
	for(int i=0;i < n ;i++) {
		cin >> ret[i];
	}
	return ret;
}

template<class T = int>
vector<T> Read(int n) {
	vector<T> ret(n);
	for (int i = 0; i < n; i++) {
		cin >> ret[i];
	}
	return ret;
}

class Solution {
		public:
			long long Ans(vector<int>& a) {
				const int N = a.size();
				vector<long long> preSum(1);
				for (const auto& i : a) { preSum.emplace_back(i + preSum.back()); }
				set<long long> que1;
				long long ans = LLONG_MAX / 2;
				for (int i = 0; i < N; i++) {
					for (int j = i; j < N; j++) {
						auto cur = preSum[j + 1] - preSum[i];
						auto it = que1.lower_bound(cur);
						if (que1.end() != it) {
							ans = min(ans, *it - cur);
						}
						if (que1.begin() != it) {
							--it; ans = min(ans, cur - *it);
						}
					}
					for (int j = 0; j <= i; j++) {
						que1.emplace(preSum[i + 1] - preSum[j]);
					}
				}
				return ans;
			}
		};
int main() {
#ifdef _DEBUG
	freopen("a.in", "r", stdin);
#endif // DEBUG	
	auto a = Read<int>();
#ifdef _DEBUG		
	//printf("K=%d", K);
	//Out(b, "b=");
	//Out(a, ",a=");
#endif // DEBUG	
	auto res = Solution().Ans(a);
	cout << res << endl;
	return 0;
}

单元测试

cpp 复制代码
vector<int> a;	
		TEST_METHOD(TestMethod11)
		{
			a = { 10,9,8,12,14 };
			auto res = Solution().Ans(a);
			AssertEx(1LL, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
huang5791478 小时前
哈希算法的抗碰撞机制与安全性增强策略4
算法
林浩杨_8 小时前
SIGIR 2026|南京大学:Video-GAR:“通过生成 Query 来验证视频语义理解”的生成增强范式
论文阅读·人工智能·算法
Elsa️7469 小时前
算法一周刷题总结
c++·算法
风合星语9 小时前
2026 机器人工程实例(五):让 Allegro Hand 在 MuJoCo 中完成接触抓取——抓取状态机、稳定抬升与受控释放
c++·python·机器人·仿真
小羊没烦恼!9 小时前
Memory 记忆设计讨论:Agent Memory 的数据模型可以怎么设计
java·开发语言·前端·c++·c#
小小程序猴19 小时前
深圳乘路资讯AI培训怎么样?课程靠谱吗?——一套课程可信度评估模型与实证分析
人工智能·算法
云上先途9 小时前
标签化服务适合哪些人?常见适用场景一次讲清
大数据·人工智能·算法·音视频
welfare9629 小时前
新号别搞:内存管理+模板初阶+STL简介
开发语言·c++
彧azz9 小时前
DFS与BFS:图遍历的两大核心算法
数据结构·学习·算法·深度优先·广度优先
宣宣猪的小花园.10 小时前
【机器学习】损失函数与梯度下降:机器如何通过“犯错”不断变好
人工智能·算法·机器学习