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

十分有意思的一道题目,设计一种方案让你支持的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\n", 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\n", 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\n", 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 }

代码君

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4443947.html

UVa 1609 (博弈) Foul Play相关推荐

  1. UVA 1609 Foul Play 不公平竞赛 (构(luan)造(gao)+递归)

    题意:有n支队伍(n是2的整数幂,2<=n<=4),打淘汰赛,胜者进入下一轮,其中1号队伍能打败至少一半的队伍,对于它不能打败的队伍l,一定存在一支它能够打败的队伍w,使得w能直接打败l, ...

  2. 紫书《算法竞赛入门经典》

    紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...

  3. 8.6 竞赛题目选讲

    8.6 竞赛题目选讲 量力而行 8-10 抄书 (UVA 714) 把一个包含m个正整数的划分成k个(1<=k<=m<=500)非空的连续子序列,使得每个正整数恰好属于一个序列.设第 ...

  4. uva 1557 - Calendar Game(博弈)

    题目链接:uva 1557 - Calendar Game 题目大意:给定一个日期,每次能够选择加一个月,或者加一天,加一个月的前提是下一个月有相应的日期,比方1.30加一个月变成2.30是不合法的. ...

  5. 【UVA - 10891 Game of Sum 】【HRBUST - 1622】 Alice and Bob (区间dp,博弈问题)

    题干: 有一个长度为N的整数序列,Alice和Bob轮流取数,Alice先取.每次玩家只能从左端或者右端 取一个或多个数,但不能两端都取.所有数都被取走后游戏结束,然后统计每个人取走的所有数之和, 作 ...

  6. UVA - 1378 A Funny Stone Game(博弈+sg函数)

    题目链接:点击查看 题目大意:给出n堆石子,两人轮流按照规则操作,不能操作的一方即为输 规则:每次将第i堆减少一个石子,将第j堆和第k堆增加一个石子,i,j,k满足(i<j<=k) 若先手 ...

  7. uva 1378 - A Funny Stone Game sg博弈

    题意:David 玩一个石子游戏. 游戏中,有n堆石子,被编号为0..n-1.两名玩家轮流取石子. 每一轮游戏.每名玩家选取3堆石子i,j,k(i<j,j<=k,且至少有一枚石子在第i堆石 ...

  8. Ferguson博弈

    清空/分割游戏也叫做Ferguson博弈. 进行游戏需要用到两个盒子,在游戏的开始,第一个盒子中有n枚石子,第二个盒子中有m个石子(n, m > 0).参与游戏的 两名玩家轮流执行这样的操作:清 ...

  9. 【CodeForces - 1038C】Gambling (博弈问题,优先队列模拟,贪心)

    题干: Two players A and B have a list of nn integers each. They both want to maximize the subtraction ...

最新文章

  1. Debevec方法计算相机响应函数CRF
  2. 由各大企业移除MongoDB,回看关系模型与文档模型之争
  3. WINCE6.0组件选择说明
  4. SQL Server 存储过程 SET 语句选项
  5. python 接口自动化_Python 接口自动化测试
  6. DPM灾难切换应用场景
  7. 机器学习-吴恩达-笔记-11-异常检测
  8. sync/atomic 库使用小结
  9. 文本居中对齐(CSS、HTML)
  10. [WTL] 改变右击SysMenu后弹出的菜单
  11. iOS开发之适配http请求
  12. arcgis for flex 学习笔记(一)
  13. postgresql 数据库 update 语句的初步使用
  14. c语言函数实现数组输入输出
  15. 宝塔linux 搭建rtmp+ffmpeg转流直播服务器
  16. uni-app学习笔记(1):模板语法
  17. 自动驾驶纯电动客车设计
  18. 从0到1:CTFer成长之路docker环境搭建
  19. Google学术映像
  20. Linux signal、sigaction的使用总结

热门文章

  1. 【Linux网络编程】原始套接字实例:MAC 头部报文分析
  2. 【物联网】QCA4010之SNTP协议
  3. 【linux网络编程】网络字节序、地址转换
  4. python数据类型转换原因_浅谈Python数据类型之间的转换
  5. JetBrains CLion C++ IDE连接wsl2(Ubuntu)时,报错“Unable to establish SSL connection“解决方案
  6. java中动态顺序死锁问题
  7. 尴尬君正,是如何被“创新”带到沟里去的?
  8. CMake基础 第8节 包含第三方库
  9. [NOTE] 关于DNSLog平台的使用
  10. C语言关键字static与extern的详细解释