说明设有2n(n<=6)个球队进行单循环比赛,计划在2 n – 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2n – 1天内每个队都与不同的对手比赛。例如n=2时的比赛安排: 队 1 2 3 4 比赛 1==2 3==4 一天 1==3 2==4 二天 1==4 2==3 三天输入格式每个测试文件只包含一组测试数据,每组输入数据为一个正整数n(n<=6)。输出格式对于每组输入数据,输出比赛安排,从第一天的安排开始,每天占一行,每行开头先输出天号,再输出当天的安排,优先给队伍编号小的队伍安排比赛,具体格式见样例输出。样例输入数据 12输出数据 1<1>1-2,3-4<2>1-3,2-4<3>1-4,2-3
解题思路:\n\n【1】用二维数组的索引位置表示队员的标号,待安排的队员数组的数值为置为1,其他都置为0;那么接下来要安排的就是那些二维数组数值为1的索引位置(用i和j表示第i个队员和第j个队员将可能发生一场比赛)。\n【2】先定下第i以及第j个队员(通过if(a[i][j]==1)来判定),然后暂时(注意这里是暂时排出因为下一天的场次比赛还需要还需要用)排出掉第i行,第j行,第i列,第j列(目的是为了安排不同的队员,不重复进行比赛),排除的方法就是将a[i][j]=3;改变二维数组值。接着安排同一天的下一场比赛信息(谁和谁比赛)。
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int a[65][65]; //为1时表示,可以被安排,为2时表示已经被安排过了 ,为3表示暂时被排除
int n;
int ans[100];
int k=1;//ans数组的索引位置的初始值
int cnt=0;//第几天
void f(int step)//step==pow(2,n-1)+1时,输出结果
{
//输出结果
int h=(int)pow(2,n)-1;//行数 最大值
int l=(int)pow(2,n);//列数最大值
int i,j,ii,jj;
if(step==(int)pow(2,n-1)+1) //符合输出条件
{
cnt++;
cout<<"<"<<cnt<<">";
for(i=1;i<k;i+=2)//第i和第j个队员的标号都存储在ans数组中,奇数存储第i个队员,偶数是第j
{
if(i==k-2)
cout<<ans[i]<<"-"<<ans[i+1]<<endl;
else
cout<<ans[i]<<"-"<<ans[i+1]<<" ";
}
for(i=1;i<=h;i++)
for(j=i+1;j<=l;j++)
if(a[i][j]==3)//将上一天中的标记为暂时被排除的队员标号(索引位置)恢复
a[i][j]=1;
k=1;//将数组ans的索引位置置为1表示重新更新ans数组的值,即下一天的场次信息
f(1);//从下一天的第一场开始安排(注意这里容易出错,不要忘记了这句代码)
}
else
{
for(i=1;i<=h;i++)
{
for(j=i+1;j<=l;j++)
{
if(a[i][j]==1) //可以被安排,之后
{
a[i][j]=2;//第i个队员和第j个队员已经确定好被安排场次啦
for(ii=1;ii<=h;ii++)
for(jj=ii+1;jj<=l;jj++)
{
if((ii==i||ii==j||jj==i||jj==j)&&a[ii][jj]==1)
a[ii][jj]=3;
}
ans[k++]=i;
ans[k++]=j;
//cout<<i<<" "<<j<<",";
f(step+1);//安排下一场次的比赛队员信息(标号)
}
}
}
}
}
int main()
{
cin>>n;
int i,j;
int h=(int)pow(2,n)-1;
int l=(int)pow(2,n);
//cout<<h<<" "<<l<<endl;
for(i=1;i<=h;i++)
for(j=i+1;j<=l;j++)
a[i][j]=1;//记录有可能发生比赛的第i个球队和第j个球队的综合情况
f(1);
return 0;
}