• UVA1609-Foul Play(构造+递归)


    Problem UVA1609-Foul Play

    Accept: 101  Submit: 514
    Time Limit: 3000 mSec

    Problem Description

    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

    题解:这个题的构造比较难,我是想不到,构造出来之后的递归就相对比较简单了。构造的方式分为四个阶段:

    1、把满足条件的队伍A和B配对,其中1打不过A,1能打过B,并且B能打过A.

    2、把1和剩下的它能打过的队伍配对.

    3、把1打不过的队伍相互配对.

    4、把剩下的队伍配对.

    能够证明按照这样的策略打过一轮之后,剩下的队伍还满足初始条件,因此可以递归求解。(构造太巧妙orz)

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1050;
     6 
     7 int n;
     8 char gra[maxn][maxn];
     9 bool vis[maxn], have_failed[maxn];
    10 
    11 void dfs(int m) {
    12     if (m == 1) return;
    13 
    14     memset(vis, false, sizeof(vis));
    15     
    16     for (int i = 2; i <= n; i++) {
    17         if (have_failed[i] || vis[i]) continue;
    18         if (gra[1][i] == '0') {
    19             for (int j = 2; j <= n; j++) {
    20                 if (have_failed[j] || vis[j]) continue;
    21                 if (gra[1][j] == '1' && gra[j][i] == '1') {
    22                     vis[j] = vis[i] = true;
    23                     have_failed[i] = true;
    24                     printf("%d %d
    ", i, j);
    25                     break;
    26                 }
    27             }
    28         }
    29     }
    30     
    31     for (int i = 2; i <= n; i++) {
    32         if (have_failed[i] || vis[i]) continue;
    33         if (gra[1][i] == '1') {
    34             vis[i] = true;
    35             have_failed[i] = true;
    36             printf("%d %d
    ", 1, i);
    37             break;
    38         }
    39     }
    40     
    41     int flag = 0, pre = 0;
    42     for (int i = 2; i <= n; i++) {
    43         if (have_failed[i] || vis[i]) continue;
    44         if (gra[1][i] == '0') {
    45             if (!flag) {
    46                 flag = 1;
    47                 pre = i;
    48             }
    49             else {
    50                 flag = 0;
    51                 vis[i] = vis[pre] = true;
    52                 printf("%d %d
    ", pre, i);
    53                 if (gra[pre][i] == '0') have_failed[pre] = true;
    54                 else have_failed[i] = true;
    55             }
    56         }
    57     }
    58     
    59     flag = 0;
    60     for (int i = 2; i <= n; i++) {
    61         if (have_failed[i] || vis[i]) continue;
    62         if (!flag) {
    63             flag = 1;
    64             pre = i;
    65         }
    66         else {
    67             flag = 0;
    68             vis[i] = vis[pre] = true;
    69             printf("%d %d
    ", pre, i);
    70             if (gra[pre][i] == '0') have_failed[pre] = true;
    71             else have_failed[i] = true;
    72         }
    73     }
    74 
    75     dfs(m >> 1);
    76 }
    77 
    78 int main()
    79 {
    80     //freopen("input.txt", "r", stdin);
    81     //freopen("output.txt", "w", stdout);
    82     while (~scanf("%d", &n)) {
    83         memset(have_failed, false, sizeof(have_failed));
    84         for (int i = 1; i <= n; i++) {
    85             scanf("%s", gra[i] + 1);
    86         }
    87 
    88         dfs(n);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    Android 中日期对话框的应用
    Unity3d 生命周期
    C#读写txt文件的两种方法介绍
    C# 获取文件夹下的所有文件夹及其文件
    NPOI 导出Excel
    SqlParameter 参数化模糊查询
    项目中的一个分页功能pagination
    MVC ---- ckeditor 循环遍历并绑定blur事件
    JQUERY链式操作实例分析
    mvc ---- ajax 提交过来的Json格式如何处理(解析)
  • 原文地址:https://www.cnblogs.com/npugen/p/9678372.html
Copyright © 2020-2023  润新知