java編寫循環賽制日程表算法問題

1.問題描述算法

設有k(k=2^m)個運動員,要進行循環賽。如今要設計一個知足如下要求的比賽日程表:設計

•  每一個選手必須與其餘k-1個選手各賽一次;遞歸

•  每一個選手一天只能賽一次;it

•   循環賽一共進行k-1天。table

2.實驗目的class

經過對循環賽日程表的練習,熟悉分治思想的應用。循環

3.分析                             方法

算法分析:next

按分治策略,咱們能夠將全部的選手分爲兩半,則n個選手的比賽日程表能夠經過n/2個選手的比賽日程表來決定。遞歸地用這種一分爲二的策略對選手進行劃分,直到只剩下兩個選手時,比賽日程表的制定就變得很簡單。這時只要讓這兩個選手進行比賽就能夠了。如上圖,所列出的正方形表是8個選手的比賽日程表。其中左上角與左下角的兩小塊分別爲選手1至選手4和選手5至選手8前3天的比賽日程。據此,將左上角小塊中的全部數字按其相對位置抄到右下角,又將左下角小塊中的全部數字按其相對位置抄到右上角,這樣咱們就分別安排好了選手1至選手4和選手5至選手8在後4天的比賽日程。依此思想容易將這個比賽日程表推廣到具備任意多個選手的情形。數據

人數K=2:

以此類推,咱們不難發現,咱們能夠用分治的方法實現,現自頂向下分解,直到分解到最簡單的狀況,即人數爲2人,這時就能夠兩兩比賽,表的填充爲對角填充的方式,而後再自底向上填充表格,具體的看上面的的循環表就很好理解了。

4.源代碼展現

​​ public static int[][] table(int n){
     //   int n = k<<1;
        int[][] a = new int[n][n];
        //構造賽程表第一行數據
        for(int i = 0; i<n;i++)
            a[0][i] = i+1;
        //採用分治算法,構造整個賽程表
        for(int r = 1;r<n;r<<=1){
            for(int i =0;i<n;i += 2*r){
                copy(a,r,r+i,0,i,r);
                copy(a,r,i,0,r+i,r);
            }
        }
        return a;
    }
    
    private static void copy(int[][] a, int tox, int toy, 
            int fromx, int fromy, int r){
        for(int i =0;i<r;i++){
            for(int j = 0;j<r;j++){
                a[tox+i][toy+j] = a[fromx+i][fromy+j];
            }
        }
        
    }
    public static void main(String[] args) {
        System.out.println("請輸入參賽人數:");
		Scanner scan =new Scanner(System.in);
		Integer read = scan.nextInt();
		int num=read.intValue();
		if(num%2!=0) {
			System.out.println("輸入人數不知足要求");
			System.exit(0);
		}
        int[][] a = table(num);
        for(int i=0;i<a.length;i++){
            for(int j = 0;j<a[0].length;j++){
                System.out.print(a[i][j] + "|");
            }
            System.out.println();
        }
}
} 
相關文章
相關標籤/搜索