SGU 138. Games of Chess 构造 难度:2

138. Games of Chess

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB

 

N friends gathered in order to play chess, according to the following rules. In the first game, two of the N friends will play. In the second game, the winner of the first game will play against another friend (maybe even the same friend who lost the first game). In the third game, the winner of the second game will play against someone else and so on.. No game will end as a draw (tie). Given the number of games each of the N friends played, find a schedule for the games, so that the above rules are obeyed.

 

Input

The first line contains the number of friends N (2<=N<=100). The second line contains N integers, separated by blanks, representing the number of games each friend played. The first number represents the number of games played by the first friend, the second number represents the number of games played by the second friend and so on..

 

Output

The first line should contain the number of games played by all the friends (it will be an integer between 1 and 10 000, for every test case). Let's suppose this number is G. Then, G lines follow, each of them containing two integers, describing the games. The first line contains the numbers of the two friends who played the first game. The friend printed first is considered to be the winner. Each of the next G-1 lines contain the integers a and b, where a<>b and a or b is the winner of the previous game. The friend printed first on the line is considered to be the winner of the game. 
It is guaranteed that for every test case there will be at least one possible scheduling of the games.

 

Sample Input

4
2 4 1 5

Sample Output

6
4 3
4 1
2 4
2 1
4 2
2 4
如果使用回路(1,2, 2,1, 2,3,...),可能会造成1 1 1 1 这种状态,
我们需要填充这样一个表,关键是不要让自己和自己对决即可
A B C D E....(总场次/2)
S:
L:

按场次从大到小排序,然后对于
A B C D E....(总场次/2)
S:
L:
每个人按照赢--(度只剩一个)输--(如果赢的填完了)输来填充,相当于把这条数列从中间截开,然后把后面那条和必要的转移作为输的,前面一条作为赢.
比如题目样例
排序过后是<5,4>,<4,2>,<2,1>,<1,3>
填充4
A,B,C,D,E,F
S:4,4,4,4,
L: 4,
填充2
A,B,C,D,E,F
S:4,4,4,4,2,2,
L:2,2, 4,
填充1
A,B,C,D,E,F
S:4,4,4,4,2,2,
L:2,2,1,1,4,
填充3
A,B,C,D,E,F
S:4,4,4,4,2,2,
L:2,2,1,1,4,3,

这个时候对于拐弯的那个重复数列设为i,设可填的非自身重叠长度l1,可填充自身重叠长度为l2,待填充长度为len,假设l1<len那么就有l1>已被填充的S序列长度,而场数排过序,如果i不是场数最大的人,不可能出现这种情况,如果i是第一个却发生转弯,也就是说没有答案
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int ,int> P;
int n;
P deg[101];
int nowdeg[101];
int heap[10001][2];
bool cmp(P p1,P p2){
    return p2.first<p1.first;
}
int main(){
    scanf("%d",&n);
    int sum=0;
    for(int i=0;i<n;i++){
        scanf("%d",&deg[i].first);
        sum+=deg[i].first;
        deg[i].second=i+1;
    }
    sort(deg,deg+n,cmp);
    int s=sum/2;
    printf("%d
",s);
    int ind=0;
    bool fl=false;
    for(int i=0;i<n;i++){
        for(int j=1;j<=deg[i].first;j++){
            if(j==deg[i].first&&!fl)heap[ind][1]=deg[i].second;
            else if(!fl){
                heap[ind++][0]=deg[i].second;
            }
            else {
                while(heap[ind][1]!=0){++ind;}
                heap[ind][1]=deg[i].second;
            }
            if(ind==s){ind=0;fl=true;}
        }
    }
    for(int i=0;i<s;i++)printf("%d %d
",heap[i][0],heap[i][1]);
    return 0;
}

  

原文地址:https://www.cnblogs.com/xuesu/p/4037070.html