循环赛日程表_分治法

题目:

  设有n=2^k个运动员要进行网球循环赛。现要设计一各满足一下要求的比赛日程表:

  1、每个选手必须与其他n-1个选手各比赛一次。

  2、每个选手一天只能赛一次。

  3、循环赛一共进行n-1天。

按照此要求可以将比赛日程表设计成一个n*n的二维表,第一列表示选手,接下来的每一列依次表示将要比赛的每一天选手。下面以8个选手为例:

思路:

  按照分治法,可将所有选手进行二分,n个选手的比赛安排可通过n/2个选手的日程表来决定。递归地用这种一分为二的策略对选手进行分割,知道只剩两个选手,日程表显然直接安排即可。

下图为8个选手的比赛日程表:

   

       图1

算法步骤:

  1、利用一个for循环初始化选手1的日程安排,即图1中的第一行。

  2、根据选手1的日程安排来安排选手2。此刻为最小规模,以相邻的每两天即四个最小单元为一组,例如选手一第一天要跟选手2比赛,那么相应选手2也要跟选手1比赛,所以将图1中的第一行第一列序号抄到第二行第二列,将第一行第二列序号抄到第二行第一列。依次,第3、4列,第5、6列,第7、8列也是。

  3、根据选手1、2的日程安排可以按照左上角数据抄到右下角,右上角数据抄到左下角安排出选手3、4的日程。

  4、最后根据前四选手,可以将所有人的日程表都安排出来。

下面是java实现完整代码:

 1 package competition;
 2 
 3 import java.util.Scanner;
 4 
 5 public class Com {
 6     private static Scanner scanner;
 7 
 8     public static void main(String [] args) {
 9         int k; //注意,n才是选手的人数,k只是问题要划分的子问题规模数,即n=2^k
10         System.out.println("输入k:");
11         scanner = new Scanner(System.in);
12         k=scanner.nextInt();
13         int a[][]=new int[pow(2,k)+1][pow(2,k)+1];
14         table(k, a);
15         for(int i=1; i<pow(2,k)+1; i++){
16             for(int j=1; j<pow(2,k); j++){
17                 System.out.print(a[i][j]+" ");
18             }
19             System.out.println(a[i][pow(2,k)]);
20         }
21     }
22     
23     static void table(int k, int [][]a){
24         int n=pow(2,k);
25         for(int i=1; i<=n; i++) a[1][i]=i;
26         int m=1;//定义M为记录每一次填充时i、j的起始填充位置
27         for(int s=1; s<=k; s++){//分治规模
28             n/=2;
29             for(int t=1; t<=n; t++)//t是每一层分治中进行对称的单位的个数
30                 for(int i=m+1; i<=2*m; i++)//控制行
31                     for(int j=m+1; j<=2*m; j++){//控制列
32                         a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];//右下角的值等于左上角的值 
33                         a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];//左下角的值等于右上角的值 
34             }
35             m*=2;
36         }
37     }
38     
39     static int pow(int a, int n) {//幂函数
40         int res=1;
41         for(int i=0; i<n; i++)
42             res*=a;
43         return res;
44     }
45 }
原文地址:https://www.cnblogs.com/LieYanAnYing/p/11628008.html