SGU 138.Games of Chess

时间限制:0.25s 空间限制:4M 题目:

    n个朋友在一起按照下面的规则依次下棋:在第一局游戏,n个人中的两个开始下棋。在第二局,第一局胜利的人将跟其他人下棋(也可能还是输了第一局人),
   在第三局第二局的胜利者将跟其他人下...依此类推。没有棋局将以平局结束,给出n个人参加过的的棋局的编号,找到一个安排棋局的方法,满足上面的规则。

输入

   第一行一个整数n(2<=n<=100).第二行有n个数,代表这n个人参加的棋局次数.

输出

   第一行是总共进行的棋局的数目k.
   接下来k行是,各个棋局参加的人的编号,要求胜利的人在前面

Sample Input

4
2 4 1 5

Sample Output

6
4 3
4 1
2 4
2 1
4 2
2 4


Solution:
因为两个可以重复对局,随便构造,按赢的场次排,对每一场从winer开排,排玩winer排loser

参考代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
int n, sum, cnt[101], pos[101];
int win[10001], lose[10001];
bool cmp (int a, int b){
	return (cnt[a] > cnt[b]);
}
int main(){
	scanf ("%d", &n);
	for (int i = 1; i <= n; ++i){
		scanf ("%d", &cnt[i]);
		sum += cnt[i];
		pos[i] = i;
	}
	sum /= 2;
	sort (pos + 1, pos + n + 1, cmp);
	int j = 1;
	for (int i = 1; i <= sum; ++i){
		if (cnt[pos[j]] == 1){
			lose[i] = pos[j];
			cnt[pos[j++]]--;
		}
		win[i] = pos[j];
		cnt[pos[j]]--;
	}
	for (int i = 1; i <= sum; ++i){
		if (lose[i]) continue;
		if (!cnt[pos[j]]) j++;
		lose[i] = pos[j];
		cnt[pos[j]]--;
	}
	printf ("%d\n", sum);
	for (int i = 1; i <= sum; ++i)
		printf ("%d %d\n", win[i], lose[i]);
	return 0;
}

  

 
posted @ 2014-07-11 11:13  keambar  阅读(347)  评论(0编辑  收藏  举报