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)

 #include <bits/stdc++.h>

 using namespace std;

 const int maxn = ;

 int n;
char gra[maxn][maxn];
bool vis[maxn], have_failed[maxn]; void dfs(int m) {
if (m == ) return; memset(vis, false, sizeof(vis)); for (int i = ; i <= n; i++) {
if (have_failed[i] || vis[i]) continue;
if (gra[][i] == '') {
for (int j = ; j <= n; j++) {
if (have_failed[j] || vis[j]) continue;
if (gra[][j] == '' && gra[j][i] == '') {
vis[j] = vis[i] = true;
have_failed[i] = true;
printf("%d %d\n", i, j);
break;
}
}
}
} for (int i = ; i <= n; i++) {
if (have_failed[i] || vis[i]) continue;
if (gra[][i] == '') {
vis[i] = true;
have_failed[i] = true;
printf("%d %d\n", , i);
break;
}
} int flag = , pre = ;
for (int i = ; i <= n; i++) {
if (have_failed[i] || vis[i]) continue;
if (gra[][i] == '') {
if (!flag) {
flag = ;
pre = i;
}
else {
flag = ;
vis[i] = vis[pre] = true;
printf("%d %d\n", pre, i);
if (gra[pre][i] == '') have_failed[pre] = true;
else have_failed[i] = true;
}
}
} flag = ;
for (int i = ; i <= n; i++) {
if (have_failed[i] || vis[i]) continue;
if (!flag) {
flag = ;
pre = i;
}
else {
flag = ;
vis[i] = vis[pre] = true;
printf("%d %d\n", pre, i);
if (gra[pre][i] == '') have_failed[pre] = true;
else have_failed[i] = true;
}
} dfs(m >> );
} int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while (~scanf("%d", &n)) {
memset(have_failed, false, sizeof(have_failed));
for (int i = ; i <= n; i++) {
scanf("%s", gra[i] + );
} dfs(n);
}
return ;
}

UVA1609-Foul Play(构造+递归)的更多相关文章

  1. uva1609 Foul Play

    思维 创造条件使一轮比赛之后仍满足1号打败至少一半,并剩下至少一个t' 紫书上的思路很清晰阶段1,3保证黑色至少消灭1半 #include<cstdio> #include<vect ...

  2. 51Nod 1013 3的幂的和 快速幂 | 乘法逆元 | 递归求和公式

    1.乘法逆元 直接使用等比数列求和公式,注意使用乘法逆元 ---严谨,失细节毁所有 #include "bits/stdc++.h" using namespace std; #d ...

  3. MVC的Views中使用递归生成Html【转】

    在开发过程中往往会有一个需求,就是将一个树状的数据结构在视图中表示出来.例如最传统的多级分类,系统中有一系列根分类,每个分类中又带有一些子分类,而我们的目标便是在页面上生成一个由ul和li嵌套组成的H ...

  4. leetcode bugfree note

    463. Island Perimeterhttps://leetcode.com/problems/island-perimeter/就是逐一遍历所有的cell,用分离的cell总的的边数减去重叠的 ...

  5. 建模算法(四)——动态规划

    其实我们对着规划接触的最多最熟悉,简单来说就是一个递归问题,递归问题简单的在的地方,编程实现的难度下降了,难的地方是如何构造递归,不好的地方是资源的浪费,但是有些地方编程实现的简单的优势可以无视掉他的 ...

  6. 77. Combinations

    题目: Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For ex ...

  7. python实现二叉树和它的七种遍历

    介绍: 树是数据结构中很重要的一种,基本的用途是用来提高查找效率,对于要反复查找的情况效果更佳,如二叉排序树.FP-树. 另外能够用来提高编码效率,如哈弗曼树. 代码: 用python实现树的构造和几 ...

  8. SQL递归查询知多少

    最近工作中遇到了一个问题,需要根据保存的流程数据,构建流程图.数据库中保持的流程数据是树形结构的,表结构及数据如下图: 仔细观察表结构,会发现其树形结构的特点: FFIRSTNODE:标记是否为根节点 ...

  9. 【Sql Server】SQL SERVER 递归查询

    SQL SERVER 2005之前的版本只能用函数方法实现,SQL SERVER 2005之后新增了CTE功能,可以利用CTE实现递归查询: CTE:公用表达式Common Table Express ...

随机推荐

  1. 【Java每日一题】20170329

    20170328问题解析请点击今日问题下方的“[Java每日一题]20170329”查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; public cla ...

  2. Java细节整理——数组与内存控制

    重点:使用Java数组之前,必须对数组对象进行初始化. 当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组的初始化完成.程序以后将不能重新改变数组对象在内存中的位置和大小. 知识点整理: ...

  3. springboot之scheduled任务调度

    springboot整合Scheduled可以方便的进行任务调度,话不多说,直接上代码 package com.rookie.bigdata; import org.springframework.b ...

  4. thinkphp3.2模块名如何不区分大小写?

    thinkphp3.2中已配置:'URL_CASE_INSENSITIVE' => true,对于控制器及操作名大小写都可以,但仍对于模块名的大小写就运行机制出错,比如:http://www.x ...

  5. react-conponent-todo

    <!DOCTYPE html> <html> <head> <script src="../../build/react.js">& ...

  6. JavaScript Hoisting(提升)

    Hoisting 是指 js 在执行代码前,默认会将变量的声明和函数的声明,提升到当前作用域顶端的行为. 这里要注意一下,只提升声明,例如: console.log(a); var a = 10; / ...

  7. 洛谷P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)

    题目描述 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到 ...

  8. cf934C. A Twisty Movement(思维题)

    题意 题目链接 Sol 这题最直接的维护区间以0/1结尾的LIS的方法就不说了. 其实我们可以直接考虑翻转以某个位置为中点的区间的最大值 不难发现前缀和后缀产生的贡献都是独立的,可以直接算.维护一下前 ...

  9. 14.Odoo产品分析 (二) – 商业板块(7) –制造(1)

    查看Odoo产品分析系列--目录 一旦你收到了库存中所需的原材料,就可以开始生产终端产品了.ERP系统的部分功能是帮助您根据可用资源调度这些订单.其中一项资源是原产品.其他资源可以包括可用劳动力或特定 ...

  10. [转] vi/vim命令模式和编辑模式各种操作

    摘要:vi 编辑器是最常用的文档创建和编辑工具,初学者应该学会简单应用vi ,学会在vi 中做简单的修改.删除.插入.搜索及替换作业:如果您是新手,不妨看看本文,或许这篇文档能让您在最短的时间内学会v ...