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; }