专栏文章

题解:B4304 [蓝桥杯青少年组省赛 2024] 通关游戏的最少能量值

B4304题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipg68p7
此快照首次捕获于
2025/12/03 11:28
3 个月前
此快照最后确认于
2025/12/03 11:28
3 个月前
查看原文
按某位大佬的意见进行了补充说明(二分排序方法)。

描述:

题面有点长,在这里帮大家分析一下:
你接到 nn 个任务,可以按任意顺序完成。
对于每个任务都有其对应的底线 xx 和消耗 yy,且保证 xyx \ge y。启动第 ii 个任务前,当前能量必须 x[i]\ge x[i];完成第 ii 个任务后会消耗 y[i]y[i] 能量。
你需要找出一个最小初始值 EE,确保这 nn 个任务在某种排序下均能完成。

算法:

二分求出最小初始值 EE,使其能完成这 nn 个任务。
需要注意的是,排序时的规则。一开始考虑欠缺,直接按任务的启动值从大到小进行了排序,结果只得了 9090 分。
CPP
bool cmp(node a,node b){
	if(a.x!=b.x)return a.x>b.x;
	return b.y>a.y;
}
显然,这样排序会导致在启动值较小消耗值很大的情况下,最终无法完成任务。从而使得二分的结果大于正确答案。
为了让各位更好的理解本题的关键——排序方法,以下进行详细的图文结合说明。
我们假设只有 22 个任务,分别用 AABB 表示。
更改后的代码如下。
CPP
bool cmp(node a,node b){
	if(a.x-a.y!=b.x-b.y)return a.x-a.y>b.x-b.y;
	return b.x>a.x;
}

AC Code:

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,l,r;
struct node{
  int x,y;
}a[N];
bool cmp(node a,node b){//重点!!!
	if(a.x-a.y!=b.x-b.y)return a.x-a.y>b.x-b.y;
	return b.x>a.x;
}
int check(int x){//判断初始值为x时,是否能完成所有任务。
	for(int i=1;i<=n;i++){
		if(x>=a[i].x)x-=a[i].y;
		else return 0;
	}
	return 1;
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&a[i].x,&a[i].y);
		r+=a[i].x+a[i].y;//将r赋为最大值。
	}
	sort(a+1,a+n+1,cmp);//关键!!!
	while(l<=r){//二分求最小初始值。
		int mid=(l+r)>>1;
		if(check(mid))r=mid-1;
		else l=mid+1;
	}
	printf("%lld",l);//输出答案。
	return 0;//好习惯。
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...