1. 程式人生 > >洛谷 P1309 瑞士輪

洛谷 P1309 瑞士輪

opera 進行 style pro hellip 比賽 log 給定 ref

題目背景

在雙人對決的競技性比賽,如乒乓球、羽毛球、國際象棋中,最常見的賽制是淘汰賽和循環賽。前者的特點是比賽場數少,每場都緊張刺激,但偶然性較高。後者的特點是較為公平,偶然性較低,但比賽過程往往十分冗長。

本題中介紹的瑞士輪賽制,因最早使用於1895年在瑞士舉辦的國際象棋比賽而得名。它可以看作是淘汰賽與循環賽的折衷,既保證了比賽的穩定性,又能使賽程不至於過長。

題目描述

2*N 名編號為 1~2N 的選手共進行R 輪比賽。每輪比賽開始前,以及所有比賽結束後,都會按照總分從高到低對選手進行一次排名。選手的總分為第一輪開始前的初始分數加上已參加過的所有比賽的得分和。總分相同的,約定編號較小的選手排名靠前。

每輪比賽的對陣安排與該輪比賽開始前的排名有關:第1 名和第2 名、第 3 名和第 4名、……、第2K – 1 名和第 2K名、…… 、第2N – 1 名和第2N名,各進行一場比賽。每場比賽勝者得1 分,負者得 0 分。也就是說除了首輪以外,其它輪比賽的安排均不能事先確定,而是要取決於選手在之前比賽中的表現。

現給定每個選手的初始分數及其實力值,試計算在R 輪比賽過後,排名第 Q 的選手編號是多少。我們假設選手的實力值兩兩不同,且每場比賽中實力值較高的總能獲勝。

輸入輸出格式

輸入格式:

輸入文件名為swiss.in 。

輸入的第一行是三個正整數N、R 、Q,每兩個數之間用一個空格隔開,表示有 2*N 名選手、R 輪比賽,以及我們關心的名次 Q。

第二行是2*N 個非負整數s1, s2, …, s2N,每兩個數之間用一個空格隔開,其中 si 表示編號為i 的選手的初始分數。 第三行是2*N 個正整數w1 , w2 , …, w2N,每兩個數之間用一個空格隔開,其中 wi 表示編號為i 的選手的實力值。

輸出格式:

輸出文件名為swiss.out。

輸出只有一行,包含一個整數,即R 輪比賽結束後,排名第 Q 的選手的編號。

輸入輸出樣例

輸入樣例#1:
2 4 2 
7 6 6 7 
10 5 20 15 
輸出樣例#1:
1

說明

【樣例解釋】

技術分享

【數據範圍】

對於30% 的數據,1 ≤ N ≤ 100;

對於50% 的數據,1 ≤ N ≤ 10,000 ;

對於100%的數據,1 ≤ N ≤ 100,000,1 ≤ R ≤ 50,1 ≤ Q ≤ 2N,0 ≤ s1, s2, …, s2N≤10^8,1 ≤w1, w2 , …, w2N≤ 10^8。

noip2011普及組第3題。

歸並排序 二路歸並

本菜雞一直認為歸並排序沒用。。這道題讓我懷疑人生。

屠龍寶刀點擊就送

#include <algorithm>
#include <cstdio>
struct node
{
    int num,s,w;
    bool operator<(node a)const
    {
        if(s==a.s) return num<a.num;
        else return s>a.s;
    }
}xs[200005],win[100005],los[100005];
int n,r,q;
void merge_sort(int l,int r)
{
    for(int i=0,j=0,k=0;k<n*2;++k)
    {
        if(i<r&&j<r)
        {
            if(win[i].s<los[j].s) xs[k]=los[j++];
            else if(win[i].s>los[j].s) xs[k]=win[i++];
            else if(win[i].s==los[j].s&&win[i].num<los[j].num) xs[k]=win[i++];
            else if(win[i].s==los[j].s&&win[i].num>los[j].num) xs[k]=los[j++];
        }
        else if(i<r&&j>=r) xs[k]=win[i++];
        else if(i>=r&&j<r) xs[k]=los[j++];
    }
}
int main()
{
    scanf("%d%d%d",&n,&r,&q);
    for(int i=0;i<n*2;++i)
    {
        scanf("%d",&xs[i].s);
        xs[i].num=i+1;
    }
    for(int i=0;i<n*2;++i) scanf("%d",&xs[i].w);
   std::sort(xs,xs+n*2);
    for(;r--;)
    {
        for(int i=0;i<n;++i)
        {
            int a=xs[i*2].w,b=xs[i*2+1].w;
            if(a>b) 
            {
                win[i]=xs[i*2];
                los[i]=xs[i*2+1];
                win[i].s++;
            }
            else if(a<b)
            {
                win[i]=xs[i*2+1];
                los[i]=xs[i*2];
                win[i].s++;
            }
        }
        merge_sort(0,n);
    }
    printf("%d\n",xs[q-1].num);
    return 0;
}

洛谷 P1309 瑞士輪