循环比赛日程表(match)(分治)

【问题描述】
    设有N个选手进行循环比赛,其中N=2M,要求每名选手要与其他N-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N-1天,要求每天没有选手轮空。
    输入:M
    输出:表格形式的比赛安排表
【样例输入】match.in
    3
【样例输出】match.out
    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
 当见到是2的几次方时,就要有分治的意思,因为2的几次方可以无限地被2分,如样例,8个人在一起打安排赛事。前4个人在一起打安排赛事和后四个个人安排赛事,
本质上都是4个人一起打,只是他们的编号不同;可以这样想:把8个人分成两个赛区,各个赛区相互打完后再交换过来打,同样,分成的两个赛区,又可以重新分成若干赛区
,再互相打‘’‘’‘
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 using namespace std;
 5 int n,half=1,k=1;
 6 int pic[100][100];
 7 int main()
 8 {
 9     scanf("%d",&n);
10     pic[0][0]=1;//从大小为1的方阵开始生成 
11     int m=1<<n;//相当于2的n次方 
12     do
13     {
14         for(int i=0;i<half;i++)
15         {
16             for(int j=0;j<half;j++)
17             {
18                 pic[i][j+half]=pic[i][j]+half;//生成右上 
19             }
20         }
21         for(int i=0;i<half;i++)
22         {
23             for(int j=0;j<half;j++)
24             {
25                 pic[i+half][j]=pic[i][j+half];//左下,由右上复制 
26                 pic[i+half][j+half]=pic[i][j];//右下,由左下复制 
27             }
28         }
29         half*=2;//当前的方阵大小 
30         k++;//生成次数+1,2的3次方就重复做3次 
31     }while(k<=n); 
32     for(int i=0;i<m;i++)
33     {
34         for(int j=0;j<m;j++)
35         {
36             printf("%d",pic[i][j]);
37         }
38         cout<<endl;
39     }
40     return 0;
41 }
原文地址:https://www.cnblogs.com/zzyh/p/6623225.html