题意:

给出2n个选手的id,能力值和初始分数

然后按分数从大到小,id从小到大排序

相邻的选手打

能力值大的分数+1

进行r轮

问你比赛过后,排名第q的选手id是多少

思路:

开始先sort一遍,每一轮比赛都归并处理

赢得人分一组,输的人分一组,保证两组有序

然后合并到原数组

持续r轮后输出结果就好了

/* ***********************************************
Author        :devil
Created Time  :2016/6/10 14:24:16
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=1e5+10;
int n;
struct wq
{
    int id,score,cap;
    void push(int a,int b,int c)
    {
        id=a;
        score=b;
        cap=c;
    }
}eg[N<<1],eg1[N],eg2[N];
bool cmp(wq a,wq b)
{
    if(a.score!=b.score) return a.score>b.score;
    return a.id<b.id;
}
void fun()
{
    int l1=1,l2=1;
    for(int i=1;i<=n;i+=2)
    {
        if(eg[i].cap>eg[i+1].cap||eg[i].cap==eg[i+1].cap&&eg[i].id<eg[i+1].id)
        {
            eg1[l1++].push(eg[i].id,eg[i].score+1,eg[i].cap);
            eg2[l2++]=eg[i+1];
        }
        else
        {
            eg1[l1++].push(eg[i+1].id,eg[i+1].score+1,eg[i+1].cap);
            eg2[l2++]=eg[i];
        }
    }
    int a=1,b=1,c=1;
    while(a<l1&&b<l2)
    {
        if(eg1[a].score>eg2[b].score||eg1[a].score==eg2[b].score&&eg1[a].id<eg2[b].id)
            eg[c++]=eg1[a++];
        else eg[c++]=eg2[b++];
    }
    while(a<l1) eg[c++]=eg1[a++];
    while(b<l2) eg[c++]=eg2[b++];
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t,r,q;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&r,&q);
        n<<=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&eg[i].score);
            eg[i].id=i;
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&eg[i].cap);
        sort(eg+1,eg+n+1,cmp);
        while(r--)
            fun();
        printf("%d\n",eg[q].id);
    }
    return 0;
}