NOIP 2011普及組 瑞士輪

2022-08-21 06:33:09 字數 2398 閱讀 9269

【背景】 

在雙人對決的競技性比賽,如桌球、羽毛球、西洋棋中,最常見的賽制是淘汰賽和迴圈賽。前者的特點是比賽場數少,每場都緊張刺激,但偶然性較高。後者的特點是較為公

平,偶然性較低,但比賽過程往往十分冗長。 

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

【題目描述】 

2*n名編號為 1~2n的選手共進行 r輪比賽。每輪比賽開始前,以及所有比賽結束後,都會按照總分從高到低對選手進行一次排名。 選手的總分為第一輪開始前的初始分數加上已參加過的所有比賽的得分和。總分相同的,約定編號較小的選手排名靠前。 每輪比賽的對陣安排與該輪比賽開始前的排名有關:第 1 名和第 2 名、第 3 名和第 4 名、……、第 2k – 1 名和第 2k名、……  、第 2n – 1 名和第2n名,各進行一場比賽。每場比賽勝者得 1 分,負者得 0 分。也就是說除了首輪以外,其它輪比賽的安排均不能事先確定,而是要取決於選手在之前比賽中的表現。 

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

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

第二行是 2*n個非負整數 s1, s2, …, s2n,每兩個數之間用乙個空格隔開,其中 si 表示編號為 i 的選手的初始分數。 

第三行是 2*n個正整數 w1, w2, …, w2n,每兩個數之間用乙個空格隔開,其中 wi 表示編號為 i 的選手的實力值。

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

【題目分析】

2011普及組第三題,是比較有難度的一道題。也在noi題庫上放到了4.1的演算法排序與效能。看似簡單,選用哪種排序很關鍵。

題很容易看懂:題目給定每個選手的初始分數及其實力值,試計算在 r 輪比賽過後,排名第 q 的選手編號是多少。

首先的思路:讀入初始分數和實力值,比實力值大小就行了,哪個大哪個分數就加。每這樣做一次就排一遍序就好,最後輸出編號就ok。

最近寫快排比較多,毫無疑問寫了快排。(剛準備說這題水)然後評測機直接就給了我乙個tle(我能怎麼辦,我也很絕望啊)

(貼乙個快排60分**)

#include#include

#include

#define maxn 200000

using

namespace

std;

struct

nodea[maxn+10

],tmp;

intcmp(node a,node b)

intmain()

sort(a+1,a+n+1

,cmp);

}cout

<

return0;

}

但是這樣算下來,時間複雜度達到了o(r*(n*logn+n)),但實際動作的次數還要加乙個常數倍。因為一共有2*n個人。因為快排的效率高是針對隨機的數列的,而這裡每一輪比賽下來,有許多人(一半人)的相對順序已經確定了,相對來說並不是隨機的,在老師的提醒下,想到了歸併排序,這樣,每一輪比賽後用o(n)的複雜度歸併一次就好,而不用快排。這樣,估算下來,時間就夠了。

(歸併ac****

(#轉侵刪#)

#include #include 

using

namespace

std;

struct

p;int

n,r,q;

p a[

200002],b[200002],ans[200002];//

ans存每一輪比賽後的結果,按名次來排,要歸併,總得有兩個有序的陣列,所以就拿a來存贏的,b來存輸的,至於為什麼a,b有序,上面已經說過了

bool pcmp(const p& a,const p&b)

void solve()

else

}int i=1,j=1,k=1

;

while (ibi)

else

}while (i];

while (j];

}int

main()

for (int i=1;i<=n;i++)

sort(ans+1,ans+1+n,pcmp);//這裡用快排效率高,一開始是乙個隨機數列

for (int i=1;i<=r;i++)

printf(

"%d\n

",ans[q].num);

return0;

}

NOIP2011普及組 瑞士輪

題目 洛谷p1309 codevs1132 vijos p1771 題目大意 要你模擬瑞士輪賽制,求出r輪後第q名選手的編號。解題思路 首先對所有選手按分數從大到小進行排序,然後模擬比賽。因為原本是排好序的,贏的加1分,輸的扣1分,所以贏的人和輸的人也是分別有序的。所以我們可以把每輪贏的人扔進乙個陣...

NOIP2011普及組第3題 瑞士輪

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

NOIP2011複賽普級組 瑞士輪

解題思路 先讀入資料,用快排對所有選手按照實力值排序,然後模擬,每打一場比賽就把贏的和輸的分為兩個有序陣列,再進行歸併,最後按要求輸出即可。程式 const maxn 100000 vara array 0.2 maxn,1.3 of longint b,c array 0.maxn,1.3 of ...