题意:
给你n名选手,以及他们的最近5次的比赛排名,让你找到是否有人能拿冠军,即这个人比所有人都强。(强的定义:此人最近五次比赛中,最少三次比另外一个人排名靠前)
思路:
我们直接从第一个人开始,将其与下一个人进行比较就行了,如果他更强,则把他当做暂时的冠军,如果他更弱,则把下一人当做暂时的冠军。以此类推,到最后只会有一个暂时的冠军(因为冠军是比所有人都强的,所以前面的败者一定不可能是冠军)。至于为什么胜者是暂时的冠军呢,因为强弱之间是没有传递关系的,A比B强,B比C强,但是C有可能比A强。例如样例二:
3
10 10 20 30 30
20 20 30 10 10
30 30 10 20 20
因此我们在O(n)的时间内就能求出暂时的冠军,然后我们再拿这个暂时的冠军去和所有人再比较一次,如果他比其他所有人都强,那他就是真正的冠军,否则就没有冠军。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 0x3f3f3f3f
const int N=5e5+5;
int h[N],e[N],nx[N],idx;
int k,T,t,n,m,ans,cnt;
int a[N][10];
bool vis[N];
priority_queue <int,vector<int>,greater<int> > q;
bool cmp(int x,int y)
{
int sum1=0,sum2=0;
for(int i=1;i<=5;i++)
if(a[x][i]<a[y][i]) sum1++;
else sum2++;
return sum1>sum2;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=5;j++)
cin>>a[i][j];
bool flag=true;
int now=1;
for(int i=2;i<=n;i++)
if(cmp(i,now)) now=i;
for(int i=1;i<=n;i++)
{
if(i==now) continue;
if(cmp(i,now))
{
flag=false;
break;
}
}
if(flag) cout<<now<<endl;
else cout<<-1<<endl;
}
return 0;
}