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

ime 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

题意:

给出2*n个人,每次第1个人和第2个人比赛,第3个人和第4个人比赛…进行r轮比赛,每轮比完赛都进行排名,求出最后第q名是谁。给出每个人的积分 s[i],每个人的能力a[i],能力大的获胜,获胜的加1分,输了的不加分。

分析:

这个题目用到了归并排序的思想,每轮比赛,把赢者放一组,输者放一组,这样单个数组也是有序的,然后进行合并。时间复杂度为0(2n*R)

AC代码:

#include <stdio.h>
#include <algorithm>
using namespace std;
struct node{
    int a,b;
    int index;
};
node ans[200005];
node temp1[200005];
node temp2[200005];

bool cmp(node a,node b)
{
    if(a.a==b.a)
        return a.index<b.index;
    return a.a>b.a;
}
int main()
{
    int T;
    int n,r,q;
    int i,j,k,l;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d %d",&n,&r,&q);
        for(i=0;i<2*n;i++)
        {
            scanf("%d",&ans[i].a);
            ans[i].index=i+1;
        }

        for(i=0;i<2*n;i++)
            scanf("%d",&ans[i].b);
        sort(ans,ans+(2*n),cmp);
        for(i=0;i<r;i++)
        {
            int cnt1=0,cnt2=0;
            for(j=0;j<2*n;j+=2)
            {
                if(ans[j].b > ans[j+1].b)
                {
                    ans[j].a++;
                    temp1[cnt1++] = ans[j];
                    temp2[cnt2++] = ans[j+1];
                }
                else
                {
                    ans[j+1].a++;
                    temp1[cnt1++] = ans[j+1];
                    temp2[cnt2++] = ans[j];
                }
            }
            j=0;k=0;l=0;
            while(j<cnt1 && k<cnt2)
            {
                if(temp1[j].a == temp2[k].a)
                {
                    if(temp1[j].index < temp2[k].index)
                    {
                        ans[l++] = temp1[j];
                        j++;
                    }
                    else
                    {
                        ans[l++] = temp2[k];
                        k++;
                    }
                }
                else if(temp1[j].a > temp2[k].a)
                {
                    ans[l++] = temp1[j];
                    j++;
                }
                else
                {
                    ans[l++] = temp2[k];
                    k++;
                }   
            }
            while(j<cnt1)
                ans[l++] = temp1[j++];
            while(k<cnt2)
                ans[l++] = temp2[k++];          
        }
        printf("%d\n",ans[q-1].index);
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值