分治法-循环赛日程表

问题描述
循环赛日程表:有n = 2^k个运动员要进行网球循环赛
赛程表满足:
每个选手必须与其他n-1个选手各赛一次
每个选手一天只能参赛一次
循环赛在n-1天内结束
解题思路
将比赛日程表设计成一个n行和n-1列的表,第i行,第j列分别填入第i个选手在第j天所遇到的选手
代码

package FenZhiJieXianFa;

/**
 * 例子:
 * 4个选手
 * ---------
 * |1|2|3|4|
 * ---------
 * |2|1|4|3|
 * ---------
 * |3|4|1|2|
 * ---------
 * |4|3|2|1|
 * ---------
 * 分治思想:将所有区域看成四块,区域1:(0,i) 区域2:(0,r+i) 区域3:(r,i) 区域4:(r,r+i)
 *  递归执行的是区域1拷贝到区域4,区域2拷贝到区域3
 * ---------
 * | 1 | 2 |
 * ---------
 * | 3 | 4 |
 * ---------
 *
 */
public class XunhuanSaiRichengBiao {
    public static int[][] table(int k){
        int n = 1<<k;
        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) {

        int[][] a = table(4);
        for(int i=0;i<a.length;i++){
            for(int j = 0;j<a[0].length;j++){
                System.out.print(a[i][j] + "ss ");
            }
            System.out.println();
        }

    }

}

运行结果

5ss 6ss 7ss 8ss 1ss 2ss 3ss 4ss 13ss 14ss 15ss 16ss 9ss 10ss 11ss 12ss 
6ss 5ss 8ss 7ss 2ss 1ss 4ss 3ss 14ss 13ss 16ss 15ss 10ss 9ss 12ss 11ss 
7ss 8ss 5ss 6ss 3ss 4ss 1ss 2ss 15ss 16ss 13ss 14ss 11ss 12ss 9ss 10ss 
8ss 7ss 6ss 5ss 4ss 3ss 2ss 1ss 16ss 15ss 14ss 13ss 12ss 11ss 10ss 9ss 
9ss 10ss 11ss 12ss 13ss 14ss 15ss 16ss 1ss 2ss 3ss 4ss 5ss 6ss 7ss 8ss 
10ss 9ss 12ss 11ss 14ss 13ss 16ss 15ss 2ss 1ss 4ss 3ss 6ss 5ss 8ss 7ss 
11ss 12ss 9ss 10ss 15ss 16ss 13ss 14ss 3ss 4ss 1ss 2ss 7ss 8ss 5ss 6ss 
12ss 11ss 10ss 9ss 16ss 15ss 14ss 13ss 4ss 3ss 2ss 1ss 8ss 7ss 6ss 5ss 
13ss 14ss 15ss 16ss 9ss 10ss 11ss 12ss 5ss 6ss 7ss 8ss 1ss 2ss 3ss 4ss 
14ss 13ss 16ss 15ss 10ss 9ss 12ss 11ss 6ss 5ss 8ss 7ss 2ss 1ss 4ss 3ss 
15ss 16ss 13ss 14ss 11ss 12ss 9ss 10ss 7ss 8ss 5ss 6ss 3ss 4ss 1ss 2ss 
16ss 15ss 14ss 13ss 12ss 11ss 10ss 9ss 8ss 7ss 6ss 5ss 4ss 3ss 2ss 1ss 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值