Swiss-system tournament | ||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||
Description | ||||||||||||||||||||||||||||||||||||||||||
A Swiss-system tournament is a tournament which uses a non-elimination format. The first tournament of this type was a chess tournament in Zurich in 1895, hence the name "Swiss system". The tournament will be held based on following rules. 2*N contestants (indexed 1, 2, ..., 2*N) will have R rounds matches. Before the first round, every contestant has an origin score. After every match, winner will get 1 score and loser will get 0 score. Before and after every round, contestants will be sorted by their scores in descending order. Two contestants with the same score will be sorted by their index with ascending order. In every round, contestants will have match based on the sorted list. The first place versus the second place, the third place versus the forth place, ..., the Kth place versus the (K + 1)th place, ..., the (2*N - 1)th place versus (2*N)th place. Now given the origin score and the ability of every contestant, we want to know the index of the Qth place contestant. We ensured that there won’t be two contestants with the same ability and the contestant with higher ability will always win the match. | ||||||||||||||||||||||||||||||||||||||||||
Input | ||||||||||||||||||||||||||||||||||||||||||
Multiple test cases. The first line contains a positive integer T (T<=10) indicates the number of test cases. For each test case, the first line contains three positive integers N (N <= 100,000), R (R <= 50), Q (Q <= 2*N), separated by space. The second line contains 2*N non-negative integers, s1, s2, ..., s2*N, si (si<= 10^8) indicates the origin score of constant indexed i. The third line contains 2*N positive integers, a1, a2, ..., a2*N, ai (ai<= 10^8) indicates the ability of constant indexed i. | ||||||||||||||||||||||||||||||||||||||||||
Output | ||||||||||||||||||||||||||||||||||||||||||
One line per case, an integer indicates the index of the Qth place contestant after R round matches. | ||||||||||||||||||||||||||||||||||||||||||
Sample Input | ||||||||||||||||||||||||||||||||||||||||||
1 2 4 2 7 6 6 7 10 5 20 15 | ||||||||||||||||||||||||||||||||||||||||||
Sample Output | ||||||||||||||||||||||||||||||||||||||||||
1 | ||||||||||||||||||||||||||||||||||||||||||
Hint | ||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||
Source | ||||||||||||||||||||||||||||||||||||||||||
"尚学堂杯"哈尔滨理工大学第六届程序设计竞赛 |
题目大意:
一共有N*2个队.每次比赛先将队伍按照规则排序,然后比对相邻两个队伍的能力值,能力值高的获胜并且得到一个分数值,输了的队伍不变。
问R轮比赛之后按照规则排序的第q个队伍的最初编号是多少。
规则:先按照队伍的分数值从大到小排序,如果分数值相等按照最初编号从小到大排序。
思路:
卡Logn的一个题,直接O(T*N*Logn*R)是会TLE的,我们尝试思维优化:
题目保证了一点:每个队伍的能力值不同,那么对应我们每轮比赛都会有N个队伍分数值增加1.N个队伍的分数值不变。
那么我们考虑将两种队伍分别存储到不同数组中,然后按序比对队头元素的大小即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
int score,val;
int pos;
}a[350000],b[350000],c[350000];
int cmp(node a,node b)
{
if(a.score==b.score)return a.pos<b.pos;
else
return a.score>b.score;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,r,q;
scanf("%d%d%d",&n,&r,&q);
for(int i=0;i<n*2;i++)scanf("%d",&a[i].score);
for(int i=0;i<n*2;i++)scanf("%d",&a[i].val),a[i].pos=i+1;
sort(a,a+2*n,cmp);
while(r--)
{
int cnt=0,cnt2=0;
for(int i=0;i<n*2;i+=2)
{
if(a[i].val>a[i+1].val)
{
a[i].score+=1;
b[cnt].score=a[i].score;b[cnt].val=a[i].val,b[cnt].pos=a[i].pos;
c[cnt2].score=a[i+1].score;c[cnt2].val=a[i+1].val;c[cnt2].pos=a[i+1].pos;
cnt2++;
cnt++;
}
else
{
a[i+1].score+=1;
b[cnt].score=a[i+1].score;b[cnt].val=a[i+1].val,b[cnt].pos=a[i+1].pos;
c[cnt2].score=a[i].score;c[cnt2].val=a[i].val;c[cnt2].pos=a[i].pos;
cnt2++;
cnt++;
}
}
int tot=0;
cnt=0,cnt2=0;
while(tot<n*2)
{
if(tot==0)
{
a[tot].score=b[cnt].score;a[tot].val=b[cnt].val;a[tot].pos=b[cnt].pos;
cnt++;
tot++;
}
else
{
if(cnt==n)
{
a[tot].score=c[cnt2].score;a[tot].val=c[cnt2].val;a[tot].pos=c[cnt2].pos,cnt2++,tot++;
}
else if(cnt2==n)
{
a[tot].score=b[cnt].score;a[tot].val=b[cnt].val;a[tot].pos=b[cnt].pos,cnt++,tot++;
}
else
{
if(b[cnt].score>c[cnt2].score)
{
a[tot].score=b[cnt].score;a[tot].val=b[cnt].val;a[tot].pos=b[cnt].pos,cnt++,tot++;
}
else if(b[cnt].score==c[cnt2].score)
{
if(b[cnt].pos<c[cnt2].pos)
{
a[tot].score=b[cnt].score;a[tot].val=b[cnt].val;a[tot].pos=b[cnt].pos,cnt++,tot++;
}
else
{
a[tot].score=c[cnt2].score;a[tot].val=c[cnt2].val;a[tot].pos=c[cnt2].pos,cnt2++,tot++;
}
}
else
{
a[tot].score=c[cnt2].score;a[tot].val=c[cnt2].val;a[tot].pos=c[cnt2].pos,cnt2++,tot++;
}
}
}
}
}
printf("%d\n",a[q-1].pos);
}
}