1. 程式人生 > >(第六場)Singing Contest 【模擬】

(第六場)Singing Contest 【模擬】

示例 src sum closed clu ould targe while ever

題目鏈接:https://www.nowcoder.com/acm/contest/144/A

標題:A、Singing Contest

| 時間限制:1 秒 | 內存限制:256M

Jigglypuff is holding a singing contest. There are 2n singers indexed from 1 to 2n participating in the contest. The rule of this contest is like the knockout match. That is, in the first round, singer 1 competes with singer 2, singer 3 competes with singer 4 and so on; in the second round, the winner of singer 1 and singer 2 competes with the winner of singer 3 and singer 4 and so on. There are n rounds in total. Each singer has prepared n songs before the contest. Each song has a unique pleasantness. In each round, a singer should sing a song among the songs he prepared. In order not to disappoint the audience, one song cannot be performed more than once. The singer who sings the song with higher pleasantness wins. Now all the singers know the pleasantness of songs prepared by all the others. Everyone wants to win as many rounds as he can. Assuming that singers choose their song optimally, Jigglypuff wants to know which singer will win the contest?
輸入描述: The input starts with one line containing exactly one integer t which is the number of test cases. (1 ≤ t ≤ 10)

For each test case, the first line contains exactly one integer n where 2n is the number of singers. (1 ≤ n ≤ 14)

Each of the next 2n lines contains n integers where aij is the pleasantness of the j-th song of the ith singer. It is guaranteed that all these 2nx n integers are pairwise distinct. (1≤ aij ≤ 109)

輸出描述: For each test case, output "Case #x: y" in one line (without quotes), where x is the test case number (starting from 1) and y is the index of the winner.

示例 1

輸入

2

1

1

2

2

1 8

2 7

3 4

5 6

輸出

Case #1: 2

Case #2: 4

題意概括:

歌唱比賽,有2^N位歌手,每位歌手準備N首歌,每首歌可以得到的分數不同,每首歌只能唱一次。1和2比,3和4比...贏了的繼續比下去,問最後誰會獲勝。每位歌手的歌曲得分用一個二維矩陣表示,A[ i ][ j ]表示第 i 位歌手唱第 j 首歌可以得到的分數。

官方題解:

由於每個選?手的策略略都是盡可能贏,所以他該認輸的時候只能認輸。
能贏的時候只要選權值?大於對?方最?大值的最?小值,?大的留留在後?面不不會 更更差。
直接模擬即可。

解題思路:

每次對決,遵循貪心的原則,排序之後lower_bound()可以打敗對手的最小值,遍歷對決可以用DFS二分一下。

AC code:

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = (1<<14)+15;
 5 int f[MAXN][15];
 6 int N;
 7 
 8 int dfs(int l, int r)
 9 {
10     if(r == l+1)
11     {
12         sort(f[l], f[l]+N);
13         sort(f[r], f[r]+N);
14         int a = lower_bound(f[l], f[l]+N, f[r][N-1
])-f[l]; 15 int b = lower_bound(f[r], f[r]+N, f[l][N-1])-f[r]; 16 if(a == N) 17 { 18 f[r][b] = 0; 19 return r; 20 } 21 else 22 { 23 f[l][a] = 0; 24 return l; 25 } 26 } 27 else 28 { 29 int mid = (l+r)>>1; 30 int x = dfs(l, mid); 31 int y = dfs(mid+1, r); 32 sort(f[x], f[x]+N); 33 sort(f[y], f[y]+N); 34 int a = lower_bound(f[x], f[x]+N, f[y][N-1])-f[x]; 35 int b = lower_bound(f[y], f[y]+N, f[x][N-1])-f[y]; 36 if(a == N) 37 { 38 f[y][b] = 0; 39 return y; 40 } 41 else 42 { 43 f[x][a] = 0; 44 return x; 45 } 46 } 47 } 48 49 int main() 50 { 51 int T_case; 52 scanf("%d", &T_case); 53 int cnt = 0; 54 while(T_case--) 55 { 56 scanf("%d", &N); 57 for(int i = 1; i <= (1<<N); i++) 58 for(int j = 0; j < N; j++) 59 { 60 scanf("%d", &f[i][j]); 61 } 62 printf("Case #%d: %d\n", ++cnt, dfs(1, (1<<N))); 63 } 64 return 0; 65 }
View Code

(第六場)Singing Contest 【模擬】