sgu 138 分类: sgu 2015-03-16 18:32 40人阅读 评论(0) 收藏
构造题
构造。构造的关键是:1.每场的胜者将在下一场出现 2.不会自己对战自己
按如下方法构造:
按场次从大到小填掉win,若只剩一场就填到lose去。
win a a a b b c c …
lose a b
最后把剩下的填到lose没填的地方即可。
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<iostream>
#include<algorithm>
const int MAXN = 105;
int n;
int cnt[MAXN] = {0};
int tot = 0;
int win[MAXN*MAXN] = {0};
int lose[MAXN*MAXN] = {0};
struct node
{
int num,sum;
}c[MAXN] = {0};
bool cmp(const node &a, const node &b){return (a.sum>b.sum);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sgu138.in","r",stdin);
freopen("sgu138.out","w",stdout);
#endif
scanf("%d",&n);
for(int i = 1 ; i <= n ; i++)
{ scanf("%d",&cnt[i]); tot += cnt[i];}
tot >>= 1;
for(int i = 1 ; i <= n ; i++)
{
c[i].num = i;
c[i].sum = cnt[i];
}
std::sort(c + 1 , c + n + 1 , cmp);
for(int i = 1 , j = 1; i <= tot ; i++)
{
if(c[j].sum == 1)
{
lose[i] = c[j].num;
c[j].sum --; j ++;
}
win[i] = c[j].num;
c[j].sum --;
}
c[n+1].sum = -1;
for (int i = 1 , j = 1; i <= tot; i++)
{
if (lose[i]) continue;
while(!c[j].sum) j++;
lose[i] = c[j].num;
c[j].sum--;
}
printf("%d\n", tot);
for (int i = 1; i <= tot; ++i)
printf("%d %d\n", win[i], lose[i]);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}