大风起兮大风起的gravatar头像
大风起兮大风起 2019-12-15 10:43:49

java编写循环赛制日程表算法问题

1.问题描述

设有k(k=2^m)个运动员,要进行循环赛。现在要设计一个满足以下要求的比赛日程表:

•  每个选手必须与其他k-1个选手各赛一次;

•  每个选手一天只能赛一次;

•   循环赛一共进行k-1天。

2.实验目的

通过对循环赛日程表的练习,熟悉分治思想的应用。

3.分析                             

算法分析:

按分治策略,我们可以将所有的选手分为两半,则n个选手的比赛日程表可以通过n/2个选手的比赛日程表来决定。递归地用这种一分为二的策略对选手进行划分,直到只剩下两个选手时,比赛日程表的制定就变得很简单。这时只要让这两个选手进行比赛就可以了。如上图,所列出的正方形表是8个选手的比赛日程表。其中左上角与左下角的两小块分别为选手1至选手4和选手5至选手8前3天的比赛日程。据此,将左上角小块中的所有数字按其相对位置抄到右下角,又将左下角小块中的所有数字按其相对位置抄到右上角,这样我们就分别安排好了选手1至选手4和选手5至选手8在后4天的比赛日程。依此思想容易将这个比赛日程表推广到具有任意多个选手的情形。

人数K=2:

           ​java编写循环赛制日程表算法问题

人数K=4:         

   ​java编写循环赛制日程表算法问题

人数K=8:

 java编写循环赛制日程表算法问题java编写循环赛制日程表算法问题

以此类推,我们不难发现,我们可以用分治的方法实现,现自顶向下分解,直到分解到最简单的情况,即人数为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();
        }
}
} 

5.程序结果展示

java编写循环赛制日程表算法问题​ java编写循环赛制日程表算法问题  java编写循环赛制日程表算法问题


打赏

最代码最近下载分享源代码列表最近下载
最代码最近浏览分享源代码列表最近浏览
qsyqa0  LV6 2021年9月4日
 LV10 2021年6月12日
2196316269  LV10 2021年2月24日
sularman  LV2 2020年10月23日
邈话12123  LV9 2020年8月8日
scywxx  LV14 2020年6月7日
smgfzx  LV2 2020年6月4日
javasript  LV6 2020年5月22日
1579054679  LV2 2020年4月29日
taocui  LV2 2020年4月27日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友