问题描述:设有n=2k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:
每个选手必须与其他n-1个选手各赛一次;
每个选手一天只能参赛一次;
循环赛在n-1天内结束。
请按此要求将比赛日程表设计成有n行和n-1列的一个表。
在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手,其中1≤i≤n,1≤j≤n-1。
#include<iostream>
#include<math.h>
using namespace std;
//构造循环赛日程表,选手的数量n=2k
int a[1024][1024];
//源方阵的左上角顶点坐标(fromx, fromy),行列数为r
//目标方阵的左上角顶点坐标(tox, toy),行列数为r
void Copy(int tox, int toy, int fromx, int fromy, int r)
{
for (int i=0; i<r; i++)
for (int j=0; j<r; j++)
a[tox+i][toy+j] = a[fromx+i][fromy+j];
}
void Table(int k)
{
int i, r;
int n = 1 << k;
//构造正方形表格的第一行数据
for (i=0; i<n; i++)
a[0][i] = i + 1;
//采用分治算法,构造整个循环赛日程表
for (r=1; r<n; r<<=1)
for (i=0; i<n; i+=2*r)
{
Copy(r, r + i, 0, i, r); //①
Copy(r, i, 0, r + i, r); //②
}
}
int main()
{
int n,t=0;
cout<<"请输入选手人数"<<endl;
cin>>n;
while(n>1){
n/=2;
t++;
}
cout<<t<<endl;
Table(t);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}