题目描述
小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件,每个事件之间相互独立且最多只会发生一次,当第 i 个事件发生时会分别让 X, Y, Z 增加Ai , Bi ,Ci 。
当游戏结束时 (所有事件的发生与否已经确定),如果 X, Y, Z 的其中一个大于另外两个之和,我们认为其获胜。例如,当 X > Y + Z 时,我们认为魏国获胜。小蓝想知道游戏结束时如果有其中一个国家获胜,最多发生了多少个事件?
如果不存在任何能让某国获胜的情况,请输出 −1 。
思路
不确定的因素有两种:
1、哪个国家赢?
只有三个国家,所以依次假设每个国家赢的情况即可。
2、该国家赢的最多选择事件是多少?
当一个国家赢时,最多选择多少个事件,使得该国的总和大于其他两国的总和。
我们使用贪心的做法。即:每个事件对该国家的贡献排序,比如:如果是a国赢,则事件的贡献=给a增加的数量-给b添加的数量-给c添加的数量。按照贡献对事件排序后,选择前面几个总和不小于等于0的事件即可。
(注意点:要开long long)
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{int a,b,c;
}ev[100005];
bool cmp1(node x,node y){return x.a-x.b-x.c>y.a-y.b-y.c;
}
bool cmp2(node x,node y){return -x.a+x.b-x.c>-y.a+y.b-y.c;
}
bool cmp3(node x,node y){return -x.a-x.b+x.c>-y.a-y.b+y.c;
}
signed main()
{int n;cin>>n;for(int i=0;i<n;i++){cin>>ev[i].a;}for(int i=0;i<n;i++){cin>>ev[i].b;}for(int i=0;i<n;i++){cin>>ev[i].c;}int ans=0;int sum=0;sort(ev,ev+n,cmp1);for(int i=0;i<n;i++){sum+=ev[i].a-ev[i].b-ev[i].c;if(sum<=0){ans=i;break;}}if(sum>0)ans=n;sum=0;sort(ev,ev+n,cmp2);for(int i=0;i<n;i++){sum+=-ev[i].a+ev[i].b-ev[i].c;if(sum<=0){ans=max(ans,i);break;}}if(sum>0)ans=n;sum=0;sort(ev,ev+n,cmp3);for(int i=0;i<n;i++){sum+=-ev[i].a-ev[i].b+ev[i].c;if(sum<=0){ans=max(ans,i);break;}}if(sum>0)ans=n;cout<<ans;}