Problem Description
设有N个选手进行循环比赛,其中N=2^M,要求每名选手要与其他N-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N-1天,要求每天没有选手轮空。
Input
输入第一行为T,表示数据组数,对于每组数据就一个M(1<=M<=10)。
Output
对于每组输入的M,输出表格形式的比赛安排表
Sample Input
1
3
Sample Output
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1
Hint
输出每个数用%3d格式。
Author
代码:
/*
把矩阵分为四个部分,先算出左上角和右上角,再选择对称法
左上角:1*1的方阵生成2*2的方阵再生成4*4的方阵。。。。。。
*/
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[1234][1234];
int main()
{
int t, n, i, j;
int m, k, x;
while(scanf("%d", &t) != EOF)
{
while(t--)
{
scanf("%d", &n);
m = pow(2, n);
k = 1;
x = 1;
a[0][0] = 1;
while(k <= n)
{
for(i = 0; i < x; i++)//构造右上方矩阵
for(j = 0; j < x; j++)
a[i][j + x] = a[i][j] + x;
for(i = 0; i < x; i++)//对称交换构造下半部分方阵
for(j = 0; j < x; j++)
{
a[i + x][j] = a[i][j + x];//左下方方阵=右上方方阵
a[i + x][j + x] = a[i][j];//右下方方阵=左上方方阵
}
x *= 2;
k++;
}
for(i = 0; i < m; i++)
{
for(j = 0; j < m; j++)
printf("%3d", a[i][j]);
printf("\n");
}
}
}
return 0;
}