循环赛日程表

【题目】

设计一个满足以下要求的比赛日程表:
(1) 每个选手必须与其他n-1个选手各赛一次;
(2) 每个选手一天只能赛一次;
(3) 循环赛一共进行n-1天。

传统方法:将比赛日程表设计为:n行 n-1列的表
(i,j)表示:第i个选手在第j 天 遇到的选手

【算法解析】

按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。

递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。

这时只要让这2个选手进行比赛就可以了。

【代码】

void Table(int k,int n,int **a){
    for(int i=1;i<=n;i++){
        a[1][i]=i;//设置日程表第一行
    }

    int m=1;//每次填充时,起始填充位置
    for(int s=1;s<=k;s++){
        n/=2;
        for(int t=1;t<=n;t++){
            for(int i=m+1;i<=2*m;i++){//控制行
                for(int j=m+1;j<=2*m;j++){//控制列
                    a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];//右下角等于左上角的值
                    a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];//左下角等于右上角的值
                }
            }
        }
        m*=2;
    }
}
时间: 2024-10-14 00:32:13

循环赛日程表的相关文章

算法之循环赛日程表

循环赛日程表 一.问题描叙 设有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的表格,(已经打好了),然后一点点按照规律打印其他小单位. 由于这题找到了原题,(并且很简单)我就把自己代码复制一下,棋盘覆盖问题是在网上找的,可以用来

循环赛日程表(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|

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

设有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