UVa OJ 1609 - Foul Play

UVa OJ 1609 - Foul Play

Problem

n支隊伍(2≤n≤1024,且n是2的整數冪)打淘汰賽,每輪都是兩兩配對,勝者進入下一輪。每支隊伍的實力固定,並且已知每兩支隊伍之間的一場比賽結果。你喜歡1號隊。雖然它不一定是最強的,但是它可以直接打敗其他隊伍中的至少一半,並且對於每支1號隊不能直接打敗的隊伍t,總是存在一支1號隊能直接打敗的隊伍t’使得t’能直接打敗t。問:是否存在一種比賽安排,使得1號隊奪冠?

Input

For each test case, the input is as follows:

  • One line containing the number of teams n, where n is a power of two and 2 ≤ n ≤ 1024. Teams are numbered from 1 to n, where team 1 is your favourite team.

  • n lines, each containing a string of n binary digits.
    The k-th digit on the j-th line is ‘1’ if team j would certainly win from team k, otherwise it is ‘0’. A team cannot play against itself, therefore the j-th digit on the j-th line is ‘0’. If j!=k, the k-th digit on the j-th line is different from the j-th digit on the k-th line.

Output

For each test case, print n − 1 lines of output, specifying a tournament schedule that ensures victory for team 1.
  The first n/2 lines describe the first round of the tournament. The next n/4 lines describe the second round, if any, etc. The last line describes the final match.
  Each line contains two integers x and y, indicating that team x plays a match against team y.
  If there are multiple tournament schedules where team 1 wins, any one of those tournament schedules will be accepted as a correct answer.

Sample Input

4
0110
0011
0000
1010
8
00111010
10101111
00010010
01000101
00110010
10101011
00010000
10101010

Sample Output

1 3
2 4
1 2
1 5
3 7
4 8
2 6
1 3
4 2
1 4

Solution

先把1隊能打敗的和不能打敗的隊伍全部區分開來,然後讓不能打敗的隊伍和能被打敗的隊伍先互相匹配。接着對1匹配能打敗的隊伍。再讓不能打敗的隊伍相互之間互相匹配,剩下的就隨便匹配。每一次能減少一半的隊伍,循環幾次即可

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 1025;
char team[maxn][maxn];
int n;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    //freopen("input.txt" , "r", stdin );
    //freopen("output.txt", "w", stdout);
    while(cin >> n){
        for(int i = 1; i <= n; ++i) {
            cin >> team[i]+1;
        }
        vector<int> win, lose;
        for(int i = 2; i <= n; ++i) {
            if(team[1][i] == '1')
                win.push_back(i);
            else lose.push_back(i);
        }
        int leftTeam = n;
        while (leftTeam > 1) {
            vector<int> winSub, loseSub, round3;
            for(int i = 0; i < lose.size(); ++i) {
                bool matched = false;
                for(int j = 0; j < win.size(); ++j){
                    if(win[j] && team[win[j]][lose[i]] == '1'){
                        cout << win[j] << ' ' <<lose[i] << '\n';
                        matched = true;
                        winSub.push_back(win[j]);
                        win[j] = 0;
                        break;
                    }
                }
                if(!matched) round3.push_back(lose[i]);
            }

            bool isOK = false;
            for(int i = 0; i < win.size(); ++i) {
                if(win[i]) {
                    if(!isOK){
                        cout << "1 " << win[i] << '\n';
                        isOK = true;
                    } else {
                        round3.push_back(win[i]);
                    }
                }
            }

            for(int i = 0; i < round3.size(); i += 2) {
                cout << round3[i] << ' ' << round3[i+1] << '\n';
                int tmp = round3[i+1];
                if(team[round3[i]][tmp] == '1')
                    tmp = round3[i];
                if(team[1][tmp] == '1') winSub.push_back(tmp);
                else loseSub.push_back(tmp);
            }

            win = winSub;
            lose = loseSub;
            leftTeam >>= 1;
        }            
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章