第七届ACM山东省赛-D Swiss-system tournament

Time Limit: 2000MS Memory limit: 131072K

题目描述
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.

输入

Multiple test cases. The first line contains a positive integer T (T<=10) indicating 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<= 108) indicates the origin score of constant indexed i.

The third line contains 2*N positive integers, a1, a2, …, a2*N, ai (ai<= 108) indicates the ability of constant indexed i.

输出

One line per case, an integer indicates the index of the Qth place contestant after R round matches.

示例输入

1
2 4 2
7 6 6 7
10 5 20 15

示例输出

1

题意:给你规定一个比赛的形式。每一个人都有一个初始的分数和能力。首先讲他们排序,分数大在前,相等的编号小的在前。然后相邻的两个人比赛,即1与2,3与4等。每次能力大的人第一分,比完之后,然后排序,再进行比赛。比赛R场,问排名为Q的人的编号。

思路:如果我们直接模拟比赛的方式那么时间复杂度是 O(nRlog(n)) ,会被卡 log(n) ,所以处理的方式就是在第一次排序完成后,我们会发现,我们可以将2×n的人分为两部分,一部分是加分的,一部分是不变的,而且他们之间也是有序的,那么我们可以采用归并的方式将比赛之后的序列排好时间复杂度为 O(RN) .

#include <bits/stdc++.h>

using namespace std;

const int Max = 100100;

struct node
{
    int sore;

    int ali;

    int Id;

    bool operator < (const node &a)const
    {
        return sore == a.sore ? Id<a.Id : sore > a.sore;
    }

}a[Max*2],b[Max],c[Max];


void Solve(int n)
{
    int num1 = 0,num2 = 0;

    for(int i = 0;i<n;i+=2)
    {
        if(a[i].ali > a[i+1].ali)
        {
            b[num1]= a[i];

            b[num1].sore++; num1++;

            c[num2++] = a[i+1];
        }
        else
        {

            b[num1]= a[i+1];

            b[num1].sore++; num1++;

            c[num2++] = a[i];
        }
    }

    int num = 0;

    int i = 0 ,j = 0;

    while(i<num1&&j<num2)
    {
        if(b[i].sore>c[j].sore || (b[i].sore == c[j].sore && b[i].Id<c[j].Id))
        {
            a[num++] = b[i++];
        }
        else a[num++] = c[j++];
    }

    while(i<num1) a[num++] = b[i++];

    while(j<num2) a[num++] = c[j++];
}


int main()
{
    int T;

    int n,m,k;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d %d %d",&n,&m,&k);

        n = 2*n;

        for(int i = 0;i<n;i++)
        {
            scanf("%d",&a[i].sore); a[i].Id = i+1;
        }

        for(int i = 0;i<n;i++) scanf("%d",&a[i].ali);

        sort(a,a+n);

        while(m--)
        {
            Solve(n);

        }
        printf("%d\n",a[k-1].Id);
    }
    return 0;
}

你可能感兴趣的:(第七届ACM山东省赛-D Swiss-system tournament)