[JOISC2022] 团队竞技

分析

首先这道题本质上离不开一个思想,就是我们贪心地选择最大的 \(a_i+b_j+c_k\)\(i,j,k\),但是碍于题目的限制,外加观察样例会发现有一些人是永远不可能选择的,例如样例 \(1\) 中的第 \(3\) 人,他的 \(b_i,c_i\) 都是最大的,不管剩余 \(2\) 人如何选,总是不满足题意。

因此,如果某个人的其中 \(2\) 项指标(或以上)是所有人中最大的,那么一定不能选他。使用优先队列维护当前 \(a,b,c\) 里的最大值,如果其中某个数列里的最大值的人,同时也是另一个数列中达到最大值的人,那么他必定不能选。开数组 \(del_i\) 表示 \(i\) 是否是不能选的。如果优先队列里开头的若干个元素都不能选,就 pop() 掉。

AC Code

#include <bits/stdc++.h>
using namespace std;
const int N=150010;
#define pii pair<int,int>
int a[N],b[N],c[N],del[N];
priority_queue<pii> x,y,z;
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i]>>c[i];
		x.push({a[i],i});
		y.push({b[i],i});
		z.push({c[i],i});
	}
	while(!x.empty()&&!y.empty()&&!z.empty())
	{
		int i=x.top().second,j=y.top().second,k=z.top().second;
		del[i]|=(b[i]==b[j])|(c[i]==c[k]);
		del[j]|=(a[i]==a[j])|(c[j]==c[k]);
		del[k]|=(a[i]==a[k])|(b[j]==b[k]);
		if(!(del[i]+del[j]+del[k]))//都能选
		{
			cout<<a[i]+b[j]+c[k];
			return 0;
		}
		while(!x.empty()&&del[x.top().second]) x.pop();
		while(!y.empty()&&del[y.top().second]) y.pop();
		while(!z.empty()&&del[z.top().second]) z.pop();
	}
	cout<<-1;
}
posted @ 2024-01-16 21:10  Crazyouth  阅读(5)  评论(0编辑  收藏  举报