循坏赛日程表
设有 n=2^k 个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表。
(1)每个选手必须与其他n-1个选手各赛一场。
(2)每个选手一天只能参赛一次。
(3)循环赛在n-1天内结束。
最后打印出的表格的第一列表示每个队伍,第i行第j列表示 第i+1个队伍在第j天对抗的队伍。
递归分治
#include <iostream>
#include <algorithm>
using namespace std;
int a[10][10];
void game_table(int n, int k)
{
if (n==2){
a[k][0]=k+1;
a[k][1]=k+2;
a[k+1][0]=k+2;
a[k+1][1]=k+1;
}
else{
game_table(n/2, k);
game_table(n/2, k+n/2);
for (int i=k; i<k+n/2; i++)//右上角
for (int j=n/2; j<n; j++)
a[i][j]=a[i+n/2][j-n/2];
for (int i=k+n/2; i<k+n; i++)//右下角
for (int j=n/2; j<n; j++)
a[i][j]=a[i-n/2][j-n/2];
}
}
int main()
{
game_table(8, 0);
for (int i=0; i<8; i++){
for (int j=0; j<8; j++)
printf("%d ", a[i][j]);
printf("\n");
}
return 0;
}
递推
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int a[10][10];
void func()
{
a[0][0]=1;
a[0][1]=2;
a[1][0]=2;
a[1][1]=1;
for (int t=1; pow(2, t)<8; t++){
int tmp=pow(2, t);
for (int i=tmp; i<tmp*2; i++){//左下角
for (int j=0; j<tmp; j++){
a[i][j]=a[i-tmp][j]+tmp;
}
}
for (int i=0; i<tmp; i++){//右上角
for (int j=tmp; j<tmp*2; j++){
a[i][j]=a[i+tmp][j-tmp];
}
}
for (int i=tmp; i<tmp*2; i++){//右下角
for (int j=tmp; j<tmp*2; j++){
a[i][j]=a[i-tmp][j-tmp];
}
}
}
}
int main()
{
func();
for (int i=0; i<8; i++){
for (int j=0; j<8; j++)
printf("%d ", a[i][j]);
printf("\n");
}
return 0;
}