【题目描述】
设有N个选手进行循环比赛,其中N=2^M,要求每名选手要与其他N-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N-1天,要求每天没有选手轮空。
【输入】
输入:M。
【输出】
输出:表格形式的比赛安排表。一行各数据间用一个空格隔开。
【输入样例】
3
【输出样例】
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
#include<bits/stdc++.h>
using namespace std;
const int maxn=1025;
int m[maxn][maxn];//记录n名选手的循环比赛表
int main()
{
int m1;
cin>>m1;
int n=1<<m1;//相当于2^m
int k=1,half=1;//half相当于方阵现在的大小
m[0][0]=1;
while(k<=m1)
{
for(int i=0;i<half;i++)//构造右上角
{
for(int j=0;j<half;j++)
{
m[i][j+half]=m[i][j]+half;
}
}
for(int i=0;i<half;i++)//对称交换构造下半部分方阵
{
for(int j=0;j<half;j++)
{
m[i+half][j]=m[i][j+half];//左下
m[i+half][j+half]=m[i][j];//右下
}
}
half*=2;
k++;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(j)
cout<<" ";
cout<<m[i][j];
}
cout<<endl;
}
return 0;
}
分析:
首先拿到这题是比较蒙的,不知道该咋写,虽然知道要用分治,但是想不起来要咋用,看这个给的例子可以发现可以把这个8*8
的分成4个4*4的,4*4可以分成4个2*2的,2*2可以分成4个1*1的这就是分治的思想了
把一个规模为n的问题分成若干个规模较小的问题使得从这些较小问题的解易于构造出整个问题的解
规律:
右上角=左下角
左上角=右下角
首先刚开始的时候可以认为是1*1的,然后先求出右上角,剩下的就好求了,根据half求,就比较简单了