参考文章:
传送门1
代码模拟实现过程:
第一步:先填好左上小角,找左下小角(对应位置+2^1)
第二步:将左下角移到右上角,左上角移到右下角。
这里有个技巧,由于最后的日程表是沿对角线对称的,所以求出下三角后可以直接得到上三角补全。
第三步:再将新填好的部分当成左上角继续填充其余的位置
结果:
代码:
#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
int Table(int k,int a[100][100])
{
//求解2^1个选手比赛日程,得到左上角元素
a[1][1] = 1;
a[1][2] = 2;
a[2][1] = 2;
a[2][2] = 1;
if(k>1)
for(int t=1; t<k; t++)
{
//左下角
for(int i=1+pow(2.0,t); i<=pow(2.0,t+1); i++)
{
for(int j=1; j<=pow(2.0,t); j++)
{
a[i][j] = a[i-(int)pow(2.0,t)][j] + (int)pow(2.0,t);
}
}
//右上角
for(int i=1; i<=pow(2.0,t); i++)
{
for(int j=1+pow(2.0,t); j<=pow(2.0,t+1); j++)
{
a[i][j] = a[j][i];
}
}
//右下角
for(int i=1+pow(2.0,t); i<=pow(2.0,t+1); i++)
{
for(int j=1+pow(2.0,t); j<=pow(2.0,t+1); j++)
{
a[i][j] = a[i-(int)pow(2.0,t)][j-(int)pow(2.0,t)];
}
}
}
else ;
}
int main()
{
int k;
int a[100][100];
cin>>k;
//求总人数n=2^k
double n=pow(2.0,k);
Table(k,a);
//输出日程表
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << a[i][j] << " ";
}
cout << endl<<endl;
}
return 0;
}
输出: