• UVa 1609 (博弈) Foul Play


    姑且把它归类为一道博弈吧,毕竟这也是在找必胜方案。

    十分有意思的一道题目,设计一种方案让你支持的1队获胜。

    题目给出了两个很重要的条件:

    • 1队能打败至少一半的队伍
    • 对于1队不能打败的黑队,一定存在一个1队能打败的灰队,使得这支灰队能够打败黑队。也就是说1队可以通过灰队间接打败黑队

    一共有2n支队伍,每轮比赛会刷掉一半的队伍,紫书上巧妙的做法就是每轮比赛后让题目给的两个性质依然成立,这样1队最终一定能胜出。

    方案如下,大致分为3个阶段:

    1. 物尽其用。依次考虑每个黑队,如果有能够打败他的灰队的话,便让这两只队伍进行比赛。当然,灰队会晋级下一轮。如果没有能够打败当前黑队而且还没有进行比赛的灰队,那么这支黑队进入后面的混战。
    2. 让1队胜出。在1队能够打败的队伍中找到一支还未进行比赛的队伍。对于其他未匹配的队伍,也进入下一步的混战。
    3. 自由混战。黑队和黑队混战,这样能保证至少消灭一半的黑队,顶多有一个黑队剩下。然后剩下的队伍继续混战。

    至于为什么这样一定会成功,还请参考紫书。

     1 #include <cstdio>
     2 #include <vector>
     3 using namespace std;
     4 
     5 const int maxn = 1030;
     6 
     7 char table[maxn][maxn];
     8 
     9 int main()
    10 {
    11     //freopen("in.txt", "r", stdin);
    12 
    13     int n;
    14     while(scanf("%d", &n) == 1 && n)
    15     {
    16         for(int i = 1; i <= n; i++) scanf("%s", table[i] + 1);
    17         vector<int> win, lose;
    18         for(int i = 2; i <= n; i++)
    19         {
    20             if(table[1][i] == '1') win.push_back(i);
    21             else lose.push_back(i);
    22         }
    23 
    24         int T = n;
    25         while(T >>= 1)
    26         {
    27             vector<int> win2, lose2, final;//进入下一轮1能打败和被打败,以及这一轮混战的队伍
    28             bool match;
    29             //阶段1:尽可能多的用灰队消灭黑队
    30             for(int i = 0; i < lose.size(); i++)
    31             {
    32                 int black = lose[i];
    33                 match = false;
    34                 for(int j = 0; j < win.size(); j++)
    35                 {
    36                     int& gray = win[j];
    37                     if(gray > 0 && table[gray][black] == '1')
    38                     {
    39                         printf("%d %d
    ", black, gray);
    40                         match = true;
    41                         win2.push_back(gray);//灰队进入下一轮
    42                         gray = 0;
    43                         break;
    44                     }
    45                 }
    46                 if(!match) final.push_back(black);//进入后面的混战
    47             }
    48             //阶段2:给1队找个对手
    49             match = false;
    50             for(int i = 0; i < win.size(); i++)
    51             {
    52                 int team = win[i];
    53                 if(team > 0)
    54                 {
    55                     if(!match) { printf("1 %d
    ", team); match = true; }
    56                     else final.push_back(team);//1已经匹配到对手,该队进入混战
    57                 }
    58             }
    59             //阶段3:自由混战,注意到黑队在final中都是挨在一起的
    60             for(int i = 0; i < final.size(); i += 2)
    61             {
    62                 printf("%d %d
    ", final[i], final[i + 1]);
    63                 int survive = final[i];
    64                 if(table[final[i + 1]][final[i]] == '1') survive = final[i + 1];
    65                 if(table[1][survive] == '1') win2.push_back(survive);
    66                 else lose2.push_back(survive);
    67             }
    68             win = win2;
    69             lose = lose2;
    70             /*for(int i = 0; i < win.size(); i++) printf("%d ", win[i]);
    71             puts("");
    72             for(int i = 0; i < lose.size(); i++) printf("%d ", lose[i]);*/
    73         }
    74     }
    75 
    76     return 0;
    77 }
    代码君
  • 相关阅读:
    java基础部分的一些有意思的东西。
    antdvue按需加载插件babelpluginimport报错
    阿超的烦恼 javaScript篇
    .NET E F(Entity Framework)框架 DataBase First 和 Code First 简单用法。
    JQuery获得input ID相同但是type不同的方法
    gridview的删除,修改,数据绑定处理
    jgGrid数据格式
    Cannot read configuration file due to insufficient permissions
    Invoke action which type of result is JsonResult on controller from view using Ajax or geJSon
    Entity model数据库连接
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4443947.html
Copyright © 2020-2023  润新知