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

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

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

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

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

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

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

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

 #include <cstdio>
#include <vector>
using namespace std; const int maxn = ; char table[maxn][maxn]; int main()
{
//freopen("in.txt", "r", stdin); int n;
while(scanf("%d", &n) == && n)
{
for(int i = ; i <= n; i++) scanf("%s", table[i] + );
vector<int> win, lose;
for(int i = ; i <= n; i++)
{
if(table[][i] == '') win.push_back(i);
else lose.push_back(i);
} int T = n;
while(T >>= )
{
vector<int> win2, lose2, final;//进入下一轮1能打败和被打败,以及这一轮混战的队伍
bool match;
//阶段1:尽可能多的用灰队消灭黑队
for(int i = ; i < lose.size(); i++)
{
int black = lose[i];
match = false;
for(int j = ; j < win.size(); j++)
{
int& gray = win[j];
if(gray > && table[gray][black] == '')
{
printf("%d %d\n", black, gray);
match = true;
win2.push_back(gray);//灰队进入下一轮
gray = ;
break;
}
}
if(!match) final.push_back(black);//进入后面的混战
}
//阶段2:给1队找个对手
match = false;
for(int i = ; i < win.size(); i++)
{
int team = win[i];
if(team > )
{
if(!match) { printf("1 %d\n", team); match = true; }
else final.push_back(team);//1已经匹配到对手,该队进入混战
}
}
//阶段3:自由混战,注意到黑队在final中都是挨在一起的
for(int i = ; i < final.size(); i += )
{
printf("%d %d\n", final[i], final[i + ]);
int survive = final[i];
if(table[final[i + ]][final[i]] == '') survive = final[i + ];
if(table[][survive] == '') win2.push_back(survive);
else lose2.push_back(survive);
}
win = win2;
lose = lose2;
/*for(int i = 0; i < win.size(); i++) printf("%d ", win[i]);
puts("");
for(int i = 0; i < lose.size(); i++) printf("%d ", lose[i]);*/
}
} return ;
}

代码君

UVa 1609 (博弈) Foul Play的更多相关文章

  1. UVa 1609 - Foul Play

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

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

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

  3. UVa 10891 (博弈+DP) Game of Sum

    最开始的时候思路就想错了,就不说错误的思路了. 因为这n个数的总和是一定的,所以在取数的时候不是让自己尽可能拿的最多,而是让对方尽量取得最少. 记忆化搜索(时间复杂度O(n3)): d(i, j)表示 ...

  4. UVa 11489 (博弈) Integer Game

    一个数字能被3整除就等价于这个数的各个数字之和被3整除. 所以一开始的时候先要拿一个能使剩下的数字是3的倍数的数. 然后就一直拿0.3.6.9直到某人不能再拿为止. #include <cstd ...

  5. 紫书 例题8-17 UVa 1609 (构造法)(详细注释)

    这道题用构造法, 就是自己依据题目想出一种可以得到解的方法, 没有什么规律可言, 只能根据题目本身来思考. 这道题的构造法比较复杂, 不知道刘汝佳是怎么想出来的, 我想的话肯定想不到. 具体思路紫书上 ...

  6. Uva 1609 Feel Good

    题面:给出长度为n的数列,然后算出其区间和乘区间最小数所能得到的最大值,并且输出区间 样例输入: 6 3 1 6 4 5 2 样例输出: 60 3 5 原题链接:https://vjudge.net/ ...

  7. Uva 10891 经典博弈区间DP

    经典博弈区间DP 题目链接:https://uva.onlinejudge.org/external/108/p10891.pdf 题意: 给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能 ...

  8. UVA 1558 - Number Game(博弈dp)

    UVA 1558 - Number Game 题目链接 题意:20之内的数字,每次能够选一个数字,然后它的倍数,还有其它已选数的倍数组合的数都不能再选,谁先不能选数谁就输了,问赢的方法 思路:利用dp ...

  9. UVA 12293 - Box Game(博弈)

    UVA 12293 - Box Game 题目链接 题意:两个盒子,一開始一个盒子有n个球.一个仅仅有1个球,每次把球少的盒子中球消掉,把多的拿一些球给这个盒子.最后不能操作的输(球不能少于1个),A ...

随机推荐

  1. NGUI 实现 透明底图遮罩 && 人物像素变黑

    今天 UI 那边要求实现一个 透明底图遮罩 与 变黑 的效果. 刚开始考虑使用 shader 实现一个 网上搜了一下,发现了这个,但是底图需要不透明才行,不然他会把 底图的不遮罩部分的透明部分 进行颜 ...

  2. 解决vsftpd日志时间问题

    解决vsftpd日志时间问题 发布时间:August 29, 2008 分类:Linux <你必须承认土也是一种艺术> <Linux下查看Apache的请求数> 最近发现vsf ...

  3. 旨在脱离后端环境的前端开发套件 - IDT Server篇

    IDT,一个基于Nodejs的,旨在脱离后端环境的前端开发套件,目的就是能让前端开发完全脱离后端的环境,无论后端是什么模板引擎(主流),都能应付自如. IDT主要包括两大部分:Server + Bui ...

  4. Android屏幕适应详解(二)

    android应用自适应多分辨率的解决方法 1. 首先是建立多个layout文件夹(drawable也一样).  在res目录下建立多个layout文件夹,文件夹名称为layout-800x480等. ...

  5. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  6. hdu 4068 SanguoSHA

    搜索下就可以了…… 代码如下: #include<iostream> #include<cstring> #include<cstdio> #include< ...

  7. Codeforces Round #337 (Div. 2) B. Vika and Squares 水题

    B. Vika and Squares   Vika has n jars with paints of distinct colors. All the jars are numbered from ...

  8. lintcode:两个数组的交

    题目 返回两个数组的交 样例 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2]. 解题 排序后,两指针找相等元素,注意要去除相同的元素 public class ...

  9. 2016网易实习生编程题:数组中两个数的和等于sum

    题目 找出数组中两个数的和等于sum的这两个数 解题 这个题目做过很多次了,利用HashMap,key为 sum-A[i] value为 i 当 加入HashMap时候A[i] 已经存在map中,ge ...

  10. RTP-实时协议

    RTP,实时协议被用来为应用程序如音频,视频等的实时数据的传输提供端到端(end to end)的网络传输功能.传输的模型可以是单点传送或是多点传送.数据传输被一个姐妹协议——实时控制协议(RTCP) ...