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;

}

 
  

  

 

你可能感兴趣的:(games)