UVA1609FoulPlay

//UVA1609FoulPlay
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
const int MAXN = (1 << 10) + 5;
char table[MAXN][MAXN];
int main() {
	int n;
	while(scanf("%d", &n) == 1 && n) {
		getchar();
		for(int i = 1; i <= n; i++) fgets(table[i] + 1, sizeof(table[i]), stdin);
		/*printf("***\n");
		*/vector<int> win, lose;
		for(int i = 2; i <= n; i++) {
			if(table[1][i] == '1') win.push_back(i);
			else lose.push_back(i); 
		}//收集所1队的对战信息
		/*for(int i = 0; i < win.size(); i++) printf("%2d", win[i]);
		printf("\n");
		for(int i = 0; i < lose.size(); i++) printf("%2d", lose[i]);
		printf("\n"); 
		*/int r = n;
		while(r > 1) {
		/*	printf("r = %d\n", r);
		*/	vector<int> win2, lose2, left;
			for(int i = 0; i < lose.size(); i++) {//i从1开始,跳过自己 
				bool match = false;
				for(int j = 0; j < win.size(); j++) {
					if(win[j] > 0 && table[win[j]][lose[i]] == '1') {//找到一组配对,用自己打得过的队,去打自己打不过的队 
						match = true;
						int& twin = win[j];
						printf("%d %d\n", win[j], lose[i]);
						win2.push_back(win[j]);//进入下一轮 
						twin = 0; //不可重复使用同一支球队
		/*				printf("win[j] = %d, j = %d\n", win[j], j);
		*/				break; 
					}
				}
				if(!match) left.push_back(lose[i]);
			}
		/*	printf("left:\n");
			for(int i = 0; i < left.size(); i++) printf("%d ---\n", left[i]);
		*/	bool tag = true;
		/*	printf("123321321313213123213\n");
		*/	for(int i = 0; i < win.size(); i++) {
				if(win[i] > 0) {
		/*			printf("win[%d] = %d\n", i, win[i]);
		*/		    if(tag) {
				        printf("%d %d\n", 1, win[i]); tag = false; 
			        }
			        else left.push_back(win[i]);
		        }
			}//给1队配对 
		/*	printf("leftsize = %d\\\\\n", left.size());
		*/	for(int i = 0; i < left.size(); i += 2) {
                printf("%d %d\n", left[i], left[i + 1]);
                int keep = left[i];
                if(table[keep][left[i + 1]] == '0') keep = left[i + 1];
                if(table[1][keep] == '1') win2.push_back(keep);
				else lose2.push_back(keep); 
			}
		    lose = lose2;
		    win = win2;
		    r >>= 1;
		} 
		
	}
	
	return 0;
}
/*
4
0110
0011
0000
1010
8
00111010
10101111
00010010
01000101
00110010
10101011
00010000
10101010
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值