题目链接:
1.三国游戏 - 蓝桥云课 (lanqiao.cn)
蓝桥杯2023年第十四届省赛真题-三国游戏 - C语言网 (dotcpp.com)
虽然这道题不难,很容易想到,但是这个视频的思路理得很清楚:
[蓝桥杯]真题讲解:三国游戏(贪心)_哔哩哔哩_bilibili
说明:
贪心的思路,借用视频的几张图说明:
sum(A[i])可以拆解成A[1]+A[2]+A[3]+.....+A[n] ,B/C同理,就容易想到构造右边的D数组。
我当时考虑的思路是对于一个国家来说,肯定是优先选它增加最大的事件,所以需要进行一个排序,但是直接排序的话,无法跟其他国家 事件增益对应,于是考虑怎么把三个国家的增益绑定在一起,才能排序,于是就构造了D这个式子。
这个题需要注意的地方:
1.题目 提到 :如果不存在任何能让某国获胜的情况,请输出 −1 。要特判不存在某国胜利的情况 ,输出-1,不要遗漏了。
2.sort函数的用法:sort(首元素的地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));
第二个参数是尾元素地址的下一个地址,刚开始直接用的+n-1,最后一个元素就没被排序,导致AC 不了。
//错误代码
sort(a,a+n-1,greater<int>());
3.计算这个d数组的时候,我就是用原数组来存的,注意:要等三个d数组的结果算出来再存入原数组,因为你先存了后面算的D数组就不是你要的差值了。这些细节需要注意,不要粗心。
//等三个D计算完 再存入原数组
for(int i=0;i<n;i++){
int aa=a[i]-b[i]-c[i];
int bb=b[i]-c[i]-a[i];
int cc=c[i]-a[i]-b[i];
a[i]=aa;
b[i]=bb;
c[i]=cc;
}
代码:
因为只有三个分支,就没有再封装成函数了。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e5+10;
int ans=0;
int a[N],b[N],c[N];
int mx=0;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
cin>>b[i];
}
for(int i=0;i<n;i++){
cin>>c[i];
}
for(int i=0;i<n;i++){
int aa=a[i]-b[i]-c[i];
int bb=b[i]-c[i]-a[i];
int cc=c[i]-a[i]-b[i];
a[i]=aa;
b[i]=bb;
c[i]=cc;
}
//sort(首元素的地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));
sort(a,a+n,greater<int>());
ans=0;int sum=0;
for(int i=0;i<n;i++){
if(sum+a[i]>0){
sum+=a[i];
ans++;
}
else break;
}
mx=max(mx,ans);
sort(b,b+n,greater<int>());
ans=0;sum=0;
for(int i=0;i<n;i++){
if(sum+b[i]>0){
sum+=b[i];
ans++;
}
else break;
}
mx=max(mx,ans);
sort(c,c+n,greater<int>());
ans=0;sum=0;
for(int i=0;i<n;i++){
if(sum+c[i]>0){
sum+=c[i];
ans++;
}
else break;
}
mx=max(mx,ans);
//不要忘了特判,不存在某国胜利的情况
if(mx==0) mx=-1;
cout<<mx<<endl;
return 0;
}