循环赛日程表(Java实现)

 1 /**
 2  * 循环赛日程表:有n = 2^k个运动员要进行网球循环赛
 3  * 赛程表满足:
 4  * 每个选手必须与其他n-1个选手各赛一次
 5  * 每个选手一天只能参赛一次
 6  * 循环赛在n-1天内结束
 7  *
 8  * 解题思路:
 9  * 将比赛日程表设计成一个n行和n-1列的表,第i行,第j列分别填入第i个选手在第j天所遇到的选手
10  * 栗子:
11  * 4个选手
12  * ---------
13  * |1|2|3|4|
14  * ---------
15  * |2|1|4|3|
16  * ---------
17  * |3|4|1|2|
18  * ---------
19  * |4|3|2|1|
20  * ---------
21  * 分治思想:将所有区域看成四块,区域1:(0,i) 区域2:(0,r+i) 区域3:(r,i) 区域4:(r,r+i)
22  *  递归执行的是区域1拷贝到区域4,区域2拷贝到区域3
23  * ---------
24  * | 1 | 2 |
25  * ---------
26  * | 3 | 4 |
27  * ---------
28  *  * @author 焦含寒
29  *
30  */
31 public class Roundrobin {
32     public static int[][] table(int k){
33         int n = 1<<k;
34         int[][] a = new int[n][n];
35         //构造赛程表第一行数据
36         for(int i = 0; i<n;i++)
37             a[0][i] = i+1;
38         //采用分治算法,构造整个赛程表
39         for(int r = 1;r<n;r<<=1){
40             for(int i =0;i<n;i += 2*r){
41                 copy(a,r,r+i,0,i,r);
42                 copy(a,r,i,0,r+i,r);
43             }
44         }
45         return a;
46     }
47
48     private static void copy(int[][] a, int tox, int toy,
49             int fromx, int fromy, int r){
50         for(int i =0;i<r;i++){
51             for(int j = 0;j<r;j++){
52                 a[tox+i][toy+j] = a[fromx+i][fromy+j];
53             }
54         }
55
56     }
57
58
59
60     public static void main(String[] args) {
61
62         int[][] a = table(4);
63         for(int i=0;i<a.length;i++){
64             for(int j = 0;j<a[0].length;j++){
65                 System.out.print(a[i][j] + "ss ");
66             }
67             System.out.println();
68         }
69
70     }
71
72 }
时间: 2024-11-09 05:03:00

循环赛日程表(Java实现)的相关文章

算法之循环赛日程表

循环赛日程表 一.问题描叙 设有n=2^k个运动员,要进行网球循环赛.现在要设计一个满足以下要求的比赛日程表 (1).每个选手必须与其他n-1个选手各赛一场 (2).每个选手一天只能赛一次 (3).循环赛一共进行n-1天 二.问题分析 按此要求可将比赛日程表设计成n行n-1列的表,在表中第 i 行和第j 列处填入第 i 个选手在第 j 天所遇到的对手. 例如,当选手的人数为8人时,其比赛日程表如下图 算法分析:按分治策略,我们可以将所有的选手分为两半,则n个选手的比赛日程表可以通过n/2个选手的

循环赛日程表(非递归)

#include<iostream> #include<vector> #include<iterator> #include<algorithm> using namespace std; /* *循环赛日程表(非递归) */ void Copy(int **map,int sr,int sl,int dr,int dl,int k) { for (int i = 0; i < k; i++) { for (int j = 0; j < k;

循环赛日程表(递归法)

#include<iostream> #include<vector> #include<iterator> #include<algorithm> using namespace std; /* *循环赛日程表(递归法) */ void Copy(int **map,int sr,int sl,int dr,int dl,int k) { for (int i = 0; i < k; i++) { for (int j = 0; j < k;

循环赛日程表 分治法

循环赛日程表 分治法 采用分治法, 逐步产生结果, 将 左上角的数字,拷贝到 右下角, 右上角的数字,拷贝到 左下角. 本程序以偶数计算,如果是奇数的话,那么就多增加一个,做轮空处理. // 采用分治法 #include <iostream> #include <cstdio> using namespace std; const int M = 1<<10; int a[M][M]; void getTable(int k) // 2^k { int n = 1<

棋盘覆盖问题&amp;循环赛日程表问题

---恢复内容开始--- 简单的分治,曾经看了好久想了好久也不会的随着时间变成最简单的题,由于刘汝佳书上说的不多,网上找到的又总是一个湖南OJ上的题(看都不愿意看)所以我还是仅说一下思想吧. 棋盘覆盖问题: 我觉得核心问题是在找不到特殊方格是假设了3个方格做特殊方格使分治继续. 循环赛日程表相对就脑残多了,关键是找到规律,然后分治问题到只有2*2的表格,(已经打好了),然后一点点按照规律打印其他小单位. 由于这题找到了原题,(并且很简单)我就把自己代码复制一下,棋盘覆盖问题是在网上找的,可以用来

循环赛日程表

[题目] 设计一个满足以下要求的比赛日程表:(1) 每个选手必须与其他n-1个选手各赛一次:(2) 每个选手一天只能赛一次:(3) 循环赛一共进行n-1天. 传统方法:将比赛日程表设计为:n行 n-1列的表(i,j)表示:第i个选手在第j 天 遇到的选手 [算法解析] 按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定. 递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单. 这时只要让这2个选手进行比赛就可以了. [代码]

循环赛日程表(用来说明算法导论上的题目!!)

设有n=2k个选手参加比赛,要求设计一个满足一下要求的比赛日程表: (1)每个选手必须与其他的n-1个选手个比赛一次: (2)每个选手每天只能赛一次 . 按此要求可以把比赛日程表设计成一个n行n-1列的二维表,其中第i行第j列表示第i个选手在 第j天比赛的选手. 代码:(分治策略) 1 #include<stdio.h> 2 #include<math.h> 3 4 void gametable(int k) 5 { 6 int a[100][100]; 7 int n,temp,

【动态规划】循环赛日程表

1 #include <stdio.h> 2 #include <stdlib.h> 3 int a[10000][10000]; 4 void huan(int row,int len) 5 { 6 int i,j; 7 for(i=0; i<len/2; i++) 8 { 9 for(j=0; j<len/2; j++) 10 { 11 a[row+i+len/2][j+len/2] = a[row+i][j]; 12 } 13 } 14 for(i=0; i<

循环赛日程表问题

#include<stdio.h> #include<math.h> void gametable(int k) { int a[100][100]; int n,temp,i,j,p,t; n=2;//k=0两个参赛选手日程可以直接求得 a[1][1]=1;a[1][2]=2; a[2][1]=2;a[2][2]=1; for(t=1;t<k;t++)//迭代处理,依次处理2^n....2^k个选手的比赛日程 { temp=n;n=n*2;//填左下角元素 for(i=te