第七届 山东省ACM Swiss-system tournament(归并思想)

Swiss-system tournament

Time Limit: 2000MS Memory Limit: 131072KB

Problem 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) 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.

Output

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

Example Input

12 4 27 6 6 710 5 20 15

Example Output

1

Hint

 

Versus

Scores after round

Index

/

(10)

(5)

(20)

(15)

Origin

/

7

6

6

7

Round 1

① VS  ②VS ③

7

6

7

8

Round 2

④ VS  ③VS ②

7

6

8

9

Round 3

④ VS ③ ①VS ②

8

6

9

9

Round 4

③ VS ④ ①VS ②

9

6

10

9

Author

  “浪潮杯”山东省第七届ACM大学生程序设计竞赛

题意:给你规定一个比赛的形式。每一个人都有一个初始的分数和能力。首先讲他们排序,分数大在前,相等的编号小的在前。然后相邻的两个人比赛,即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 index;
    bool operator < (const node &a)const
    {
        return sore == a.sore ? index<a.index : sore > a.sore;
    }
}a[Max*2],b[Max],c[Max];   ///a为排序数组  b为赢的那一个

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].index<c[j].index))
            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].index = i+1;
        }
        for(int i = 0;i<n;i++)
            scanf("%d",&a[i].ali);

        sort(a,a+n);

        while(m--)   ///进行m轮比赛
            Solve(n);

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




原文地址:https://www.cnblogs.com/zswbky/p/6717883.html