书上的解法:
每一轮分四个阶段:
第一阶段:对队1不能消灭的队伍,尽量用队1能消灭的队伍去消灭。
第二阶段:队1任选一个能战胜的队伍 消灭。
第三阶段: 队1不能消灭的队伍自相残杀。
第四阶段:所有未比赛的队伍任意杀。
这样每一轮结束之后都能保证队1至少能战胜一半的队伍。
代码写的烂,只能给自己以后看看。
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define rep(i,n) for(int i=0 ;i<(n) ;i++)
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn=1024 ;
int n;
char s[maxn+10];
bool win[maxn+10][maxn+10];
bool vis[maxn+10];
bool done[maxn+10];
void read()
{
memset(done,0,sizeof done);
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=n;j++)
{
win[i][j]= s[j]=='1'?1:0;
}
}
}
void match()
{
memcpy(vis,done,sizeof done);
for(int i=2;i<=n;i++) if(!vis[i]&&!win[1][i])
{
int find=-1;
for(int j=1;j<=n;j++) if(!vis[j]&&win[1][j]&&win[j][i])//最中间那个条件很重要
{
find=j;
break;
}
if(~find)
{
vis[i]=1;
done[i]=1;
vis[find]=1;
printf("%d %d\n",find,i);
}
}
for(int i=1;i<=n;i++) if(!vis[i]&&win[1][i])
{
done[i]=1;
vis[i]=1;
vis[1]=1;
printf("%d %d\n",1,i);
break;
}
int now=-1;
for(int i=1;i<=n;i++) if(!vis[i]&&!win[1][i])
{
if(now==-1)
{
now=i;
}
else
{
printf("%d %d\n",now,i);
vis[now]=vis[i]=1;
if(win[now][i]) done[i]=1;
else done[now]=1;
now=-1;
}
}
if(~now)
{
for(int i=1;i<=n;i++) if(!vis[i]&&i!=now)
{
printf("%d %d\n",now,i);
vis[now]=vis[i]=1;
if(win[now][i]) done[i]=1;
else done[now]=1;
break;
}
now=-1;
}
for(int i=1;i<=n;i++) if(!vis[i])
{
if(now==-1)
{
now=i;
}
else
{
printf("%d %d\n",now,i);
vis[now]=vis[i]=1;
if(win[now][i]) done[i]=1;
else done[now]=1;
now=-1;
}
}
}
void work()
{
int num=n;
while(num>1)
{
match();
num/=2;
}
}
int main()
{
while(~scanf("%d",&n))
{
read();
work();
}
return 0;
}