循環賽日程表_分治法


題目:

  設有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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM