分治法实现循环赛日程安排表
c++
首先了解一下循环日程安排表问题
设有n=2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
1、每个选手必须与其他n-1个选手各赛一次;
2、每个选手一天只能参赛一次;
3、循环赛在n-1天内结束。
按此要求,可将比赛日程表设计成一个n 行n-1列的二维表,在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。
以下是代码
递归
#include<iostream>
using namespace std;
void fill(int a[][50],int m)
{
int j,l;
if(m==1)
{
a[1][0]=a[0][1]=2;//完成一个小的左上角单元
a[0][0]=a[1][1]=1;
}
else
{
fill(a,m/2);
for(j=0;j<m;j++) //填写左下角
for(l=m;l<m*2;l++)
{
a[l][j]=a[l-m][j]+m;
}
for(;j<2*m;j++) //填写右上角
for(l=0;l<m;l++)
{
a[l][j]=a[l+m][j-m];
}
for(j=m;j<2*m;j++) //填写右下角
for(l=m;l<2*m;l++)
{
a[l][j]=a[l-m][j-m];
}
}
}
int main(){
int m,i,j,k=0,a[50][50];
cin>>m;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
a[i][j]=0;
fill(a,m/2);
for(i=0;i<m;i++)
{for(j=0;j<m;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
非递归
#include<iostream>
using namespace std;
int main(){
int m,k=0,i,j,l,a[50][50];
cin>>m;
//n=m;
while(m!=1){ //判断是2的几次方赋给k
k++;
m=m/2;
}
// for(i=0;i<n;i++)//第一列填写所有选手编号
// {
// a[i][0]=i+1;
// }
a[1][0]=a[0][1]=2;//完成一个小的左上角单元
a[0][0]=a[1][1]=1;
for(i=1;i<k;i++)
{
m*=2;
for(j=0;j<m;j++) //填写左下角
for(l=m;l<2*m;l++)
{
a[l][j]=a[l-m][j]+m;
}
for(;j<2*m;j++) //填写右上角
for(l=0;l<m;l++)
{
a[l][j]=a[l+m][j-m];
}
for(j=m;j<2*m;j++) //填写右下角
for(l=m;l<2*m;l++)
{
a[l][j]=a[l-m][j-m];
}
}
for(i=0;i<m*2;i++)
{for(j=0;j<2*m;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}