循环赛日程表问题研究

合集下载

网球循环赛日程表

网球循环赛日程表

一、问题表述:设有n个运动员要进行网球循环赛。

设计一个满足以下要求的比赛日程表,(1) 每个选手必须与其他n-1个选手各赛一次;(2) 每个选手一天只能赛一次;(3) 当n是偶数时,循环赛进行n-1天,当n是奇数时,循环赛进行n天二、分析问题题目是要n名运动员进行循环比赛。

当n为偶数时,正好每天都可以两两一组,与其余的n-1个选手比赛,只需n-1天;而当n为奇数,每天将有一个选手轮空,比赛将持续n天。

可以采用的算法如下:1.算法一:使用分治法当n为偶数时,可以讲问题分为两个部分n/2; 然后继续划分,知道最后剩余两名选手单独比赛。

当n为奇数时,增设一个虚拟选手,运动员为n+1个,将问题转化为是偶数的情形。

当选手与虚拟选手比赛时,表示轮空,因此只需要关注n为偶数的情形。

a)当n/2为偶数时,与n = 2^k情形类此。

b)当n/2为奇数时,增设一个虚拟的选手,递归返回的将有轮空的选手,可以讲在前面n/2轮比赛的选手与后面n/2轮空的选手进行比赛。

2.算法二:利用边是奇数的正多边形。

特点:以多边形中的任意一个顶点画对称轴,其余偶数对顶点相互对称。

N名选手编号为1~n,将其画成一个正多边形。

a)所以当n为奇数时,第一天1号休息,其余以一号为对称轴,两两对称打比赛,第二天开始一次轮流休息,其余一休息的那个人编号为对称轴,两两比赛。

这样比赛可进行n天。

如图:12345678012345678对称轴此时n=9,为奇数,从0开始每天有一个人轮空对称轴b) 当n 为偶数时,取出编号最大的,其他的组成一个正多边形,n 号一次顺序与1,2,。

n -1号选手比赛,其他与a )相同。

如图所示:(图中是从0开始编号)123456789 9N=2k 时9三、 理论分析算法及实现1. 算法一:使用分治法a) 算法的思路:按分治策略,可以将所有的选手对分为两组(如果n 是偶数,则直接分为n/2每组,如果n 是奇数,则取(n+1)/2每组),n 个选手的比赛日程表就可以通过为(n/2或(n+1)/2)个选手设计的比赛日程表来决定。

循环赛日程表问题研究讲解

循环赛日程表问题研究讲解

学年论文题目循环赛日程表问题研究学生指导教师年级2009级专业软件工程系别软件工程学院计算机科学与信息工程学院哈尔滨师范大学2012年6月论文提要本文采用分治算法来解决循环赛日程表的安排问题。

通过对问题的详细分析,列出1到10个选手的比赛日程表,找出两条规则,作为算法实现的依据,而后采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

同时也介绍了循环赛日程表问题的另一种解法多边形解法,这种方法另辟蹊径,巧妙地解决了循环赛日程表问题,运行效率较高。

循环赛日程表问题研究摘要:本文采用分治算法来解决循环赛日程表的安排问题。

根据算法的设计结果,采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

同时也介绍了循环赛日程表问题的另一种解法,这种方法另辟蹊径,想法独特,运行效率较高。

关键词:循环赛日程表问题;分治法一、题目描述设有n 个运动员要进行网球循环赛。

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

当n 是奇数时,循环赛进行n 天。

二、问题分析循环赛日程表可以采用分治法实现,把一个表格分成4个小表格来处理,每个小表格都是一样的处理方法,只是参数不同。

分析过程具体如下:1、n=1(表2-1)2.、n=2(表2-2)3、n=3(1) 添加一个虚拟选手4#,构成n+1=4(2) 4/2=2,分两组,每组各自安排(1 2),(3 4) (3) 每组跟另一组分别比赛(拷贝)这是四个人比赛的(表2-3) 4人赛程(4) 把虚选手置为0 (表2-4)3人赛程11 2 21 1234 2 1 4 3 3 4 1 2 43211 2 3 0 2 1 0 3 3120 3 2 1这是三个人比赛的安排4、n=4,见表2-35、n=5(1) 加一个虚选手,n+1=6。

安排好6个人的比赛后,把第6个人用0表示即得5人的。

循环赛日程表算法

循环赛日程表算法

循环赛日程表算法循环赛是一种比赛形式,每个参赛者都要与其他参赛者进行比赛,比赛的次数与参赛者的数量有关。

循环赛通常用于团体比赛,如足球、篮球、棒球等。

在循环赛中,每个参赛者都要与其他参赛者进行比赛,以便确定最终的排名。

循环赛日程表算法是一种用于生成循环赛日程表的算法,它可以帮助组织者快速、准确地生成日程表,以便比赛能够顺利进行。

循环赛日程表算法的基本原理是将参赛者分成两组,每组的人数相等。

然后,每个参赛者都要与另一组的每个参赛者进行比赛。

比赛的次数等于参赛者数量的一半。

例如,如果有8个参赛者,那么每个参赛者都要进行4场比赛。

在每场比赛中,每个参赛者都要与另一个参赛者进行比赛,以便确定胜者和败者。

胜者将获得3分,平局将获得1分,败者将获得0分。

最终,参赛者将按照得分进行排名。

循环赛日程表算法的实现方法有很多种。

其中一种常用的方法是使用矩阵来表示比赛日程表。

矩阵的行和列分别表示参赛者和比赛轮次。

在矩阵中,每个元素表示一场比赛,其中包含两个参赛者的编号和比赛结果。

例如,如果第一轮比赛中,参赛者1和参赛者2进行比赛,参赛者1获胜,那么矩阵中的元素就是(1,2,3),其中1表示参赛者1的编号,2表示参赛者2的编号,3表示参赛者1获胜。

生成循环赛日程表的算法可以分为两个步骤。

首先,需要确定参赛者的编号和比赛轮次。

参赛者的编号可以使用数字或字母来表示,比赛轮次可以使用数字来表示。

例如,如果有8个参赛者,那么参赛者的编号可以从1到8,比赛轮次可以从1到4。

其次,需要确定每场比赛的参赛者和比赛结果。

这可以通过循环嵌套来实现。

在每个比赛轮次中,需要将参赛者分成两组,然后将每组的参赛者进行配对,以便进行比赛。

比赛结果可以通过随机数来生成,以增加比赛的随机性。

循环赛日程表算法的优点是可以确保每个参赛者都能与其他参赛者进行比赛,以便确定最终的排名。

此外,循环赛日程表算法还可以减少比赛的时间和成本,因为每个参赛者只需要进行一次比赛,而不需要进行多次比赛。

循环赛日程表任意人数

循环赛日程表任意人数

/ 一、问题描述:设有n个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表:1.每个选手必须与其他n-1个选手各赛一次;2.每个选手一天只能参赛一次;3.N是偶数时,循环赛在n-1天内结束。

N是奇数时,循环赛进行N天.请按此要求将比赛日程表设计成有n行和n-1列(或n列)的一个表。

在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。

其中≤i≤n,≤j≤n-1。

二、基本思想(所用数组下标从开始)区分队伍的奇偶情况(奇数时有队伍要轮空)。

1.n为奇数时首先,选取前n-1个运动员构建初始对阵关系序列:b(1,n-1,2,n-2,...,i,n-i,...)然后,计算第i天比赛对应的序列:序列b+i(i取值范围为~n)(计算时)序列的每个元素均加i,并且当序列元素加i后如果大于n则将其对n求余序列b+1 -> 序列b+2 -> ...... -> 序列b+n-1 -> 序列b+n第天第天第n-1天第n-1天(比赛时)相邻运动员对阵(即下标,2表示运动员对阵,下标,4表示运动员对阵...),并且在第i天第i号运动员轮空。

2.n为偶数时首先,选取前n-1个运动员按照其数情况安排比赛然后,将第n号运动员填入前n-1个运动员比赛安排中的轮空位置,并依据其建立第n行比赛日程安排*/#include<iostream>using namespace std;void odd_table ( int **a , int n){int i,j;int *b; //指向对阵关系数组//建立初始对阵关系(,n-1,2,n-2,...,i,n-i)b=new int [n]; //0下标不用for(i=1;i<=n/2;i++){b[2*i-1]=i;b[2*i]=n-i;}for(i=1;i<=n;i++)//i控制天数变化{a[i][i]=0; //n为奇数时在第i天第i号运动员轮空for(j=1;j<=(n-1);j+=2){//第i天m1与m2对阵int m1=((b[j]+i)<=n)?(b[j]+i):(b[j]+i)%n;int m2=((b[j+1]+i)<=n)?(b[j+1]+i):(b[j+1]+i)%n;a[m1][i]=m2;a[m2][i]=m1;}}}int main(){int i,j; //循环控制变量int days; //比赛天数int n; //参赛队数int **a; //日程表cout<<"请输入运动员人数:";cin >> n;if (n<=1) cout<<"数据非法";else{a=new int* [n+1]; //行表示运动员days = n%2==0?n-1:n; //比赛天数,n是偶数时,n-1天。

循环赛日程表问题优秀文档

循环赛日程表问题优秀文档
int n = end - start + 1; if(n==2) {
a[start][1] = start+1; a[start+1][1] = start; return; } int mid = (end + start)/2; table(a, start, mid); table(a, mid+1, end); copy(a,start,end); }
华南师范大学计算机学院 – 计算机算法
循环赛日程表
2021/8/22
作者:杨劲松
内容提要
问题描述 题思路 程序实现
2021/8/22
问题描述
问题描述:
设有n(n = 2k)位选手参加网球循环赛,循环赛共进行n-1天,每位选 手要与其他n-1位选手比赛一场,且每位选手每天必须比赛一场,不能轮 空。
int mid = (end + start)/2;
{ for(int if(n==2)
——循环赛一共进行n-1天。
j=m;j<n;j++)
{
a[i][j] = a[i+m][j-m];
}
}
} 2021/8/22
程序实现
2021/8/22
感谢观看
for(int i=mid+1;i<=end;i++)
ifnotr(miindt =i=(meindd+1+;is<t=aerntd);/i2+;+) c{—i{ic设不nnoott—有能ppinnffyy(o循 n轮s((==raat((ani,,环空eenssrnnt=ttt赛。aadd>j=2rr=tt--一mk,,eess)e;位共nnttjnaa<dddrr选进n))tt;;;|++j|手行+s+11t参na);;i-nr1加tt天<m网=。=球0)n循r/e2环t;u赛rn;,循环赛共进行n-1天,每位选手要与其他n-1位选手比赛一场,且每位选手每天必须比赛一场, {}for(i{}fnotr(iia=[nsitt]a[jrj=t]m;;i=j<<=anm[;iijd+;-+im)+]+[)j-m]; i—r——aa—— fi—a—i—nnnoe[[[tttsssrt————————u(nmmtttiaaarn循 循 每 循 循循 循 每n=iirrrtddttt;]]]i环环个环环 环环个e=[[[==111nm]]]赛赛选赛赛 赛赛选((dee===idnn-一一手一一 一一手+sssddsttt1共共必共共 共共必taaa++a;rrri<rttt进进须进进 进进须sst+++=tt+111aa行行与行行 行行与e;;;rrn1tt其其nnnnnnd));//------;22111111i他他+;;天天天天 天天+nn)。。。。 。。--11个个选选手手各各赛赛一一场场;;

循环赛日程表

循环赛日程表

//n/2为奇数
代码实现
❖ void copyodd(int n) // n/2为奇数的合并
{
int m=n/2;
for(int i=0;i<m;i++)
{
b[i]=m+i;
b[m+i]=b[i];
}
//未完

代码实现
for(i=0;i<m;i++){
for(int j=0;j<m+1;j++)
}
时间复杂度分析
1. N/2为奇数 T(n)=O(4k)
有2个循环结构 基本语句是循环体内的赋值语句 T(n)=2+(+2)=0(4k),
2.N/2为偶数T(n)=O(4k)
有2个循环结构 基本语句是循环体内的赋值语句 T(n)=3=0(4k),

调试运行
N=4 N=3
3
0
1
3
2
1
0
第输一天出要求<0,(n=4时) 第二天 1>=
0
1
A
1
0
<2, 3>= B<1

第一天
0>=
A
B
B
A
第三天
2
3
A
<3
3
2

A
B
B
A
2>=
B
输第一出天 要第二求天 (第三n天=4时)
0
1
2
3
1
0
3
2
2
3
0
1
3
2
1
0
AC BD

算法之循环赛日程表

算法之循环赛日程表

算法之循环赛⽇程表循环赛⽇程表⼀.问题描叙设有n=2^k个运动员,要进⾏⽹球循环赛。

现在要设计⼀个满⾜以下要求的⽐赛⽇程表(1).每个选⼿必须与其他n-1个选⼿各赛⼀场(2).每个选⼿⼀天只能赛⼀次(3).循环赛⼀共进⾏n-1天⼆.问题分析按此要求可将⽐赛⽇程表设计成n⾏n-1列的表,在表中第 i ⾏和第j 列处填⼊第 i 个选⼿在第 j 天所遇到的对⼿。

例如,当选⼿的⼈数为8⼈时,其⽐赛⽇程表如下图算法分析:按分治策略,我们可以将所有的选⼿分为两半,则n个选⼿的⽐赛⽇程表可以通过n/2个选⼿的⽐赛⽇程表来决定。

递归地⽤这种⼀分为⼆的策略对选⼿进⾏划分,直到只剩下两个选⼿时,⽐赛⽇程表的制定就变得很简单。

这时只要让这两个选⼿进⾏⽐赛就可以了。

如上图,所列出的正⽅形表是8个选⼿的⽐赛⽇程表。

其中左上⾓与左下⾓的两⼩块分别为选⼿1⾄选⼿4和选⼿5⾄选⼿8前3天的⽐赛⽇程。

据此,将左上⾓⼩块中的所有数字按其相对位置抄到右下⾓,⼜将左下⾓⼩块中的所有数字按其相对位置抄到右上⾓,这样我们就分别安排好了选⼿1⾄选⼿4和选⼿5⾄选⼿8在后4天的⽐赛⽇程。

依此思想容易将这个⽐赛⽇程表推⼴到具有任意多个选⼿的情形。

算法实现步骤:(1)当k=1时,即⼈数为2⼈,此情况为最简单的情况此时表为1 22 1(2)当k=2时,⼈数为4⼈,循环表为1 2 3 42 1 4 33 4 1 2 4 3 2 1(3)当k=3时,⼈数为8⼈,此时循环表为1 2 3 4 5 6 7 82 1 4 3 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 46 5 8 7 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1以此类推,我们不难发现,我们可以⽤分治的⽅法实现,现⾃顶向下分解,直到分解到最简单的情况,即⼈数为2⼈,这时就可以两两⽐赛,表的填充为对⾓填充的⽅式,然后再⾃底向上填充表格,具体的看上⾯的k=1,k=2,k=3时形成的循环表就很好理解了。

循环赛日程表

循环赛日程表

算法设计与分析实验报告循环赛日程表一.问题描述设有n位选手参加循环赛,设计循环赛日程表,要求:每位选手必须和其余n-1个选手比赛;每位选手每天只能比一场比赛;若n为奇数,则比赛n天;若n为偶数,则比赛n-1天。

二.实验目的熟悉分治法的思想并掌握其运用。

三.实现方式编译环境:Dev-C++算法思路:使用分治法的思想,给n个选手安排日程表转化为给n/2个选手安排日程表,直到问题规模变成给两个选手安排日程。

日程表可以用一个二维数组表示,数组的大小为k (n<=2^k),第i行第j列的数组值表示第i个选手在第j-1天比赛的对手(第1列表示选手的编号,假定选手的编号为1,2,3…恰为数组的行数)。

划分:n个选手的日程表可以由n/2个选手的日程表合并而得。

解决:当只有两个选手比赛的时候,可以直接给出其日程表,得到一个2×2的数组。

当有4个选手参加比赛的时候,则将两个2×2的数组合并,得到一个4×4的数组。

以此类推,n 个选手的日程表由n-1个选手的日程表合并而成。

合并规则为:若n 为偶数,则会得到一个n ×n 的表格;若n 为奇数,需要比赛n 天,则会得到一个n ×(n+1)的表格且每一天必定有一位选手轮空。

因此在合并的时候要先把表格扩充为(n+1)×(n+1)的表格,然后再消除虚拟的选手(用0表示轮空)。

例:n=3时赛程表为:当n=6时,将两个n=3的赛程表合并,在同一天轮空的选手便可在该天比赛。

然后再补上表格右边的元素。

设当前要合并的数组的长度为s,表格左下角的元素可由左上角的元素+s而得:表格右上角的元素由前一行决定:表格右下角的元素由表格右上角对应元素所决定:四.结果验证(1)调用函数IsRight()可验证所得结果的正确性(即每行,每列没有相同的元素),若结果可行,则返回1;否则返回0;(2)调用DoTest()函数可以把2~N(N用const定义为一个常量,可随时修改)个选手的赛程表作为数据集写到文件RoundMatch中。

分治法循环赛日程表实验报告

分治法循环赛日程表实验报告

西北农林科技大学信息工程学院《算法分析与设计》综合训练实习报告题目:分治法循环赛日程表学号姓名专业班级指导教师实践日期2011年5月16日-5月20日目录一、综合训练目的与要求 (1)二、综合训练任务描述 (1)三、算法设计 (1)四、详细设计及说明 (3)五、调试与测试 (4)六、实习日志 (6)七、实习总结 (6)八、附录:核心代码清单 (6)一、综合训练目的与要求本综合训练是软件工程专业重要的实践性环节之一,是在学生学习完《算法分析》课程后进行的综合练习。

本课综合训练的目的和任务:(1)巩固和加深学生对算法分析课程基本知识的理解和掌握;(2)培养利用算法知识解决实际问题的能力;(3)掌握利用程序设计语言进行算法程序的开发、调试、测试的能力;(4)掌握书写算法设计说明文档的能力;(5)提高综合运用算法、程序设计语言、数据结构知识的能力。

二、综合训练任务描述假设有n=2k 个运动员要进行网球循环赛。

设计一个满足一下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次(2)每个选手一天只能赛一次(3)循环赛一共进行n-1天利用Java语言开发一个界面,输入运动员的个数,输出比赛日程表。

对于输入运动员数目不满足n=2k时,弹出信息提示用户。

三、算法设计(1) 文字描述假设n位选手顺序编号为1,2,3……n,比赛的日程表是一个n行n-1列的表格。

第i行j列表示第i号选手在第j天的比赛对手,根据分治法,要求n个选手的比赛日程,只要知道其中一半的比赛日程,所以使用递归最终可以分到计算两位选手的比赛日程,然后逐级合并,得出结果。

(2) 框图图 1(3) 伪代码static int a[][] = new int[100][100];static int athletes;static int n;static void copy(int n) {// 核心代码int m = n / 2;for (int i = 1; i <= m; i++)for (int j = 1; j <= m; j++) {a[i][j + m] = a[i][j] + m;// 由左上角数的值算出对应的右上角数a[i + m][j] = a[i][j + m];// 把右上角数的值赋给对应的左下角数a[i + m][j + m] = a[i][j];// 把左上角数的值赋给对应的右下角数}}static void tournament(int n) // 分治算法,递归调用自己{if (n == 1) {a[1][1] = 1;return;}tournament(n / 2); // 分治copy(n); // 合并}public static void main(String[] args) {n=getText();athletes = n;tournament(n);}}四、详细设计及说明(1)输入一个数字n,根据(x&(x-1))==0判断n是否等于2^k。

【算法-分治策略应用】循环赛日程表问题

【算法-分治策略应用】循环赛日程表问题

【算法-分治策略应⽤】循环赛⽇程表问题⼀、分治策略基本思想1、Divide将原始问题划分或者归结为规模较⼩的⼦问题(多数情况下是划分成2个)2、Conquer递归或迭代求解每个⼦问题3、Combine将⼦问题的解综合得到原问题的解注意:1、⼦问题与原始问题性质完全⼀样2、⼦问题之间可彼此独⽴地求解3、递归停⽌时⼦问题可直接求解⽐较典型的应⽤例⼦是“归并排序法”和“快速排序法”,详细可以参考屈婉玲等编著的《算法设计与分析》(第2版)P26和P37,此处不再赘述。

⼆、题⽬分析和建模1. 问题描述设有n=2k个选⼿要进⾏⽐赛,设计的⽐赛⽇程表需要满⾜以下要求:1)每个选⼿必须与其他n-1个选⼿各赛⼀次;2)每个选⼿⼀天只能赛⼀次;3)整场循环赛⼀共进⾏n-1天。

2. 题⽬建模将⽐赛⽇程表设计成n⾏×n-1列的⼀个表,表中第i⾏第j列的元素表⽰第i个选⼿在第j天所遇到的选⼿。

(1)⾸先看只有两个选⼿的⽇程表(k=1,n=2,2⾏×1列表格,循环赛进⾏1天):表1 循环赛⽇程表(2⼈)(2)四个选⼿的⽇程表(k=2,n=4,4⾏×3列表格,循环赛进⾏3天):⾸先n=22,所以应该退化到求解两个2⼈循环赛的问题,⽇程表构建如下:表1 循环赛⽇程表(2⼈) 表2 循环赛⽇程表(2⼈)将表2抄在表1右侧构成表1*,将表1抄在表2右侧构成表2*,将表1*与表2*按次序上下拼接,构成表3:表3 循环赛⽇程表(4⼈)由于表1和表2中运动员完全不同,拼接之后每⼀⾏和每⼀列都不会存在两个相同号码,也就是说拼接后不会产⽣⼀个选⼿在同⼀天和另外⼀个选⼿⽐赛两次的情况,说明这种拼接是合理的。

(3)⼋个选⼿的⽇程表(k=3,n=8,8⾏×7列表格,循环赛进⾏7天)n=23,⾸先应该退化到4⼈循环赛问题,再退化到2⼈循环赛问题,4⼈退化到2⼈已在(2)中详细描述,此处只说明如何退化到4⼈问题:表3 循环赛⽇程表(4⼈) 表4 循环赛⽇程表(4⼈)拼接⽅法与(2)中相同,构成表5:表5 循环赛⽇程表(8⼈)三、算法设计(1)设计思想:设n=2k采⽤分治策略,将所有参加⽐赛的选⼿分成两部分,n=2k个选⼿的⽐赛⽇程表就可以通过两个n=2k-1个选⼿的⽐赛⽇程表来决定。

循环赛的日程安排题解

循环赛的日程安排题解

循环赛的日程安排题解循环赛是一种比赛形式,参赛队伍之间要进行多轮比赛,每个队伍都要与其他队伍进行一次比赛。

在给定的参赛队伍数量下,如何安排循环赛的日程是一个常见的问题。

对于循环赛的日程安排,有多种方法可以考虑。

下面我将从几个角度来回答这个问题。

1. 完全循环赛:每个队伍都与其他队伍进行一次比赛。

如果参赛队伍的数量是偶数,可以采用以下方法进行日程安排:将参赛队伍分成两组,每组的队伍数量相等。

每轮比赛,将一组的队伍固定在场上,另一组的队伍按照某种规则进行轮换。

每个队伍在比赛结束后,都与另一组的队伍进行比赛,直到所有的比赛都完成。

2. 部分循环赛:如果参赛队伍的数量是奇数,无法进行完全循环赛。

可以考虑以下方法进行日程安排:将参赛队伍分成两组,每组的队伍数量相等。

每轮比赛,将一组的队伍固定在场上,另一组的队伍按照某种规则进行轮换。

每个队伍在比赛结束后,都与另一组的队伍进行比赛,直到所有的比赛都完成。

最后一轮比赛,可以将一组的队伍固定在场上,另一组的队伍轮空,或者可以进行友谊赛。

3. 轮换规则:在循环赛的日程安排中,轮换规则是一个重要的考虑因素。

常见的轮换规则有以下几种:瑞士轮制,根据每个队伍的胜负情况,将队伍分成不同的组别,每轮比赛中,同组别的队伍进行比赛。

轮换表,制定一张表格,按照特定的顺序安排队伍之间的比赛。

随机轮换,通过随机抽签或者其他方式,确定每轮比赛中的对阵情况。

总结起来,循环赛的日程安排需要考虑参赛队伍的数量,以及采用何种轮换规则。

以上所述只是一些常见的方法和思路,具体的日程安排还需要根据实际情况进行调整和制定。

分治法——循环赛日程表

分治法——循环赛日程表

分治法——循环赛⽇程表1、问题描述:有n=2^k个远动员选⼿,设计⽐赛⽇程表实现:(1)每个选⼿必须与n-1个选⼿⽐赛(2)每个选⼿⼀天只⽐赛⼀场(3)⽐赛共进⾏n-1天输⼊:n⼈输出:n⾏n-1列,第i⾏第j列表⽰第i个选⼿第j天遇到的对⼿,不包含第⼀列表⽰为选⼿编号举例:2⼈1 22 12、问题分析通过化⼤为⼩,分⽽治之的思想,将多⼈的⽐赛⽇程缩⼩为2⼈的⽇程。

以此倒推所有⼈的⽇程。

注意多⼈⽇程规律:以四⼈为例:1 2 | 3 42 1 | 4 3----------3 4 | 1 24 3 | 2 1这样⼀个矩阵分为四个区,左上和右下⼀样,左下和右上⼀样,且右上是左上对应的数字加了n/2.3、代码实现1 #include <stdio.h>2 #include <string.h>34#define N 1285int matrix[N][N] = {0};67void fun(int n)8 {9int i;10int j;11if (n<=0)12 {13return;14 }15if (n>2)16 {17 fun(n/2);18for (i=1;i<=n/2;i++)19 {20for (j=n/2+1;j<=n;j++)21 {22 matrix[i][j] = matrix[i][j-n/2] + n/2;23 }24 }25for (i=n/2+1;i<=n;i++)26 {27for (j=1;j<=n/2;j++)28 {29 matrix[i][j] = matrix[i-n/2][j+n/2];30 }31 }32for (i=n/2+1;i<=n;i++)33 {34for (j=n/2+1;j<=n;j++)35 {36 matrix[i][j] = matrix[i-n/2][j-n/2];37 }38 }39 }40else41 {42 matrix[1][1] = 1;43 matrix[1][2] = 2;44 matrix[2][1] = 2;45 matrix[2][2] = 1;46 }47 }4849void main()50 {51 fun(8);5253int i,j;54for (i=1;i<=8;i++)55 {56for (j=1; j<=8; j++)57 {58 printf("%d ",matrix[i][j]);59 }60 printf("\n");61 }62 }。

扩展循环赛日程表算法研究

扩展循环赛日程表算法研究
第 23 卷增 刊 Vol.23 suppl.
文章编号 1008-0562(2004)增刊-0050-03
辽宁工程技术大学学报 Journal of Liaoning Technical University
扩展循环赛日程表算法研究
2004 年 6 月 Jun. 2004
刘 超 刘建辉 林 森
辽宁工程技术大学 电子与信息工程系, 辽宁 阜新 123000
for(i=1;i<=N;i++) a[ i][0 ]=i;
然后将第 1 行各列中填入相应列序号加 1 所得 数字即第 1 行第 1 列填入 2 第 1 行第 2 列填入 3 第 1 行第 N 1 列填入 N 对于奇数个选手 将比 赛 N 天 天时相应数字为初始化时的 0 表示轮空 而对偶数个选手时的排序 恰好 N 1 天完成比赛 相应程序程序为
在程序[2~4]实现时 我们首先定义一个数组 考虑到 C 语言的数组是从第 0 行第 0 列开始存储数 据的 因此将数组的第 0 列设为代表选手编号的一 列 则在程序中数组的第 0 列填入的数字应与行序 号相同 用以表示选手的序号 即第 1 行第 0 列中 填入 1 第 2 行第 0 列中填入 2 第 N 行第 0 列 中应填入 N 采用程序如下
辽宁工程技术大学学报journalofliaoningtechnicaluniversity2004年6月jun2004收稿日期作者简介20040510刘超1981男辽宁朝阳人硕士研究生本文编校孙树江文章编号100805622004增刊005003扩展循环赛日程表算法研究刘超刘建辉林森辽宁工程技术大学电子与信息工程系辽宁阜新123000摘动员的赛程排列问题对于非2n个运动员的赛程排列问题并不能很好地解决因此针对经典的循环赛日程表算法进行了相应的扩展要循环赛日程表算法是一个经典的计算机算法它是分治算法的一个典型应用但经典的循环赛日程表算法只能解决2n个运使其能够完成非2n个运动员的赛程安排是值得考虑和实现的一个问题并且应以相应的程序予以实现关键词计算机算法经典循环赛扩展循环赛日程表中图号tp915文献标识码astudyonextendingofroundrobincalendaralgorithmliuchaoliujianhuilinsendepartmentofelectricandinformationengineeringliaoningtechnicaluniversityfuxin123000chinatheroundrobincalendaralgorithmisaclassicalcomputeralgorithmanditisarepresentativeapplicationofthedivideandrulealgorithmbutclassicalcomputeralgorithmcansolvematcharrangementof2nplayersonlyitcantresolvetheproblemofnot2nplayerssowedosomecorrespondingextendedfortheroundrobincalendaralgorithmmakeitresolvetheproblemofnot2nplayersitisworthconsideringandrealizingandalsorealizeitbyprogramkeywordscomputeralgorithmtheclassicalroundrobinabstracttheextendedroundrobinalgorithmcalendar0引言分治法是一个比较典型也很常见的计算机算法它不仅可以用来设计各种算

篮球循环赛安排问题

篮球循环赛安排问题

论文题目:篮球循环赛安排问题姓名1:李麒鹏学号:10140102013专业:数学与应用数学姓名2:洪津津学号:10140102026 专业:数学与应用数学姓名3:刘娜娜学号:10140102019专业:数学与应用数学2012年5月5日目录一.摘要 (3)二.问题重述 (3)三.问题分析 (3)四.模型假设 (4)五.符号说明 (4)六.模型建立 (4)七.模型求解 (7)八.结果分析验证及模型检验 (7)九.模型评价 (9)十.参考文献 (9)一.摘要篮球是世界上公认的三大球类运动之一,在世界各地都有着广泛而深远的影响,在我国篮球也是一项十分普及的运动,深受广大人民群众尤其是青少年的喜爱。

本文主要针对某校十个院系举办的篮球循环赛,考虑到每支球队休息时间的公平性和优劣情况,根据现行赛程安排方法,建立出不同的日程安排模型,再针对其中一个模型展开分析,讨论此模型是否公平,并给出相应的改进办法。

n为偶数时采用“逆时针旋转法”进行求解,得到上限为(n-4)/2,则本次比赛的上限为3。

在评价赛程安排公平性方面,我们采用方差检验进行模型评价,最终得到相对合理的结果。

关键词:休息时间公平性日程安排逆时针旋转法二.问题重述十个队参加学校举行的篮球循环赛,为了保持比赛的公平性,每队需要得到的休息应大体相同,每队每次打完比赛后至少能隔一场不比赛,需给出至少一个比赛日程表。

三.问题分析(一)循环赛的轮数每个参赛队赛毕一场(轮空队除外),称为一轮结束。

计算循环赛的轮数,目的在于计划整个比赛所需用的时间或期限,是比赛日程安排的主要依据。

其计算方法:Y=轮次数,n=参赛队数如果参赛队为偶数 Y=n-1 即轮次数=参赛队数-1如果参赛队为奇数,则:比赛轮数=参赛队数。

注:双循环赛的轮数是单循环赛轮数的加倍。

本次共有10个参赛队,且只考虑单循环,因此,Y=9.(二)循环赛的场数循环赛的场数是指参赛队之间互相轮流比赛全部结束的总场数。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表
{r et ai n n&1;
} voi d ma kee opy ( i n t m
{遗( rl /2) >1&&odd∽))c opyodd( n);
els e c opy( n); l voi d eop yodd ( i nt n) {i n t m=n/2; f or ( int i- -O;i<m;i ++)
el se a[m+i 】【j 】-a 【i 】【j 】+m; l f or O=l ;j <m;j ++) {a [i l[m+j 】- b[ i+j 】; a【b“+j 】Ⅱm+j 】- i ; }
l 1
分析算法的 时间性能: 当n/2为 奇数时,基本 语句的执行次 数是:
T∞=∑2+∑( ∑+∑2) =0( 42)
算法如下: voi d t o uma( i nt n) {if ( n==1) {a[ O][ 0]=1;r et urn;J tour ed(n/2); copy( n); J voi d copy( hat I n {i n t re =n /2 ;
f or (hat i -- O;i <m;i ++) f or (i nt j =0.j<玎嘶++)
随着计算机技术的蓬勃发展计算机教学将面临新的挑战机房管理也将越来越受到学校的重视在以后的工作中机房管理人员应不断总结积累经验提高工作效率提高自身的管理水平和技术水平更好地为学校教育教学服务
煎垫壅进查塑
÷
…}
ቤተ መጻሕፍቲ ባይዱ
垫查±鱼
利用分治法设计 循环赛日程表

循环赛日程表问题

循环赛日程表问题
1
5
4
3
2
7
6
10*
8
2
9
1
5
4
3
8
3
6
7
9
10*
2
1
5
4
9
10*
4
6
8
7
3
2
1
5
10*
9
7
5
6
8
4
3
2
1
当n=9/10时,规则同上(n=9时用一位虚拟选手补全)
总结:
观察右上角灰色部分可知:【规则一】:每一行数值从左到右循环递增; 每一列上也是6~10循环递增; 第一行第m+1(下标从0开始)列的值为(m+1)+1,依次向右递增;【规则二】:右下角的块:因为比赛是两两之间进行的,所以右下角由右上角决定。
代码实现
代码实现
运行结果
循环赛日程表
/9
内容简介
问题描述
A
解题思路
B
程序实现
C
知识延伸
D
问题描述:设有n(n = 2k)位选手参加网球循环赛,循环赛共进行n-1天,每位选手要与其他n-1位选手比赛一场,且每位选手每天必须比赛一场,不能轮空。每个选手必须与其他n-1个选手各赛一场;每个选手一天只能赛一场。
问题描述
解题思路
采用分治法实现,把一个表格分成4个小表格来处理,每个小表格都是一样的处理方法,只是参数不同。分析过程具体如下:
n=1
n=2
选手
第一天
1
1
2
2
1
n=3
n=4
选手
第一天
第二天
第三天

算法分析思维分析,以循环赛日程表为例

算法分析思维分析,以循环赛日程表为例

算法分析思维分析,以循环赛⽇程表为例第⼀步:分治法的简单思想在计算机科学中,分治法是⼀种很重要的算法。

字⾯上的解释是“分⽽治之”,就是把⼀个复杂的问题分成两个或更多的相同或相似的⼦问题,再把⼦问题分成更⼩的⼦问题……直到最后⼦问题可以简单的直接求解,原问题的解即⼦问题的解的合并。

这个技巧是很多⾼效算法的基础,如排序算法(,归并排序),傅⽴叶变换()等等。

任何⼀个可以⽤计算机求解的问题所需的计算时间都与其规模有关。

问题的规模越⼩,越容易直接求解,解题所需的计算时间也越少。

例如,对于n个元素的排序问题,当n=1时,不需任何计算。

n=2时,只要作⼀次⽐较即可排好序。

n=3时只要作3次⽐较即可,…。

⽽当n较⼤时,问题就不那么容易处理了。

要想直接解决⼀个规模较⼤的问题,有时是相当困难的。

分治法的设计思想是,将⼀个难以直接解决的⼤问题,分割成⼀些规模较⼩的相同问题,以便各个击破,分⽽治之。

分治策略是:对于⼀个规模为n的问题,若该问题可以容易地解决(⽐如说规模n较⼩)则直接解决,否则将其分解为k个规模较⼩的⼦问题,这些⼦问题互相独⽴且与原问题形式相同,递归地解这些⼦问题,然后将各⼦问题的解合并得到原问题的解。

这种算法设计策略叫做分治法。

第⼆步:分治法的理论基础如果原问题可分割成k个⼦问题,1<k≤n ,且这些⼦问题都可解并可利⽤这些⼦问题的解求出原问题的解,那么这种分治法就是可⾏的。

由分治法产⽣的⼦问题往往是原问题的较⼩模式,这就为使⽤递归技术提供了⽅便。

在这种情况下,反复应⽤分治⼿段,可以使⼦问题与原问题类型⼀致⽽其规模却不断缩⼩,最终使⼦问题缩⼩到很容易直接求出其解。

这⾃然导致递归过程的产⽣。

分治与递归像⼀对孪⽣兄弟,经常同时应⽤在算法设计之中,并由此产⽣许多⾼效算法。

 2.1分治法所能解决的问题⼀般具有以下⼏个特征: 1) 该问题的规模缩⼩到⼀定的程度就可以容易地解决 2) 该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦结构性质。

分治法解决循环赛日程表的递归方程)

分治法解决循环赛日程表的递归方程)

分治法解决循环赛日程表的递归方程)分治法是一种解决问题的算法思想,它将一个大问题划分为若干个小问题,并分别解决这些小问题,最后将小问题的解合并得到原问题的解。

这种思想在循环赛日程表的递归方程中也可以得到应用。

循环赛日程表是指参赛团队之间进行循环对战的赛程安排表。

在一个参赛团队数量为n的循环赛中,每个团队需要与其他n-1个团队进行比赛,总共进行了(n-1) * n / 2场比赛。

解决循环赛日程表的递归方程可以分为三个步骤:1. 将参赛团队分为两个子集,分别是左侧子集和右侧子集。

如果参赛团队数量为奇数,可以将最后一个团队放入左侧子集。

2. 分别为左侧子集和右侧子集构造循环赛日程表。

这可以通过递归调用解决循环赛日程表的递归方程来实现。

递归的终止条件是子集中只有一个团队,此时不需要进行比赛。

3. 将左侧子集和右侧子集的日程表合并得到整个循环赛日程表。

合并的过程是将左侧子集的日程表和右侧子集的日程表进行对应位置的合并,合并后的结果即为整个循环赛日程表。

通过以上三个步骤,我们可以递归地构造出循环赛日程表。

这种分治法的思想能够将原问题划分为多个小问题来解决,从而提高问题的解决效率。

在实际应用中,分治法可以有效地解决循环赛日程表的问题。

通过将问题划分为若干个小问题,并逐步解决这些小问题,最后再将小问题的解合并得到原问题的解,可以高效地构造出循环赛日程表。

分治法是一种解决问题的有效算法思想,它可以应用于循环赛日程表的递归方程。

通过将问题划分为若干个小问题,并逐步解决这些小问题,最后将小问题的解合并得到原问题的解,可以高效地构造出循环赛日程表。

这种算法思想能够提高问题的解决效率,是解决循环赛日程表问题的一种有效方法。

循环赛日程表问题

循环赛日程表问题

循环赛⽇程表问题输⼊正整数k表⽰有n=2^k个运动员进⾏循环⽐赛,需要设计⽐赛⽇程表。

每个选⼿与其他n-1个选⼿各赛⼀次;每个选⼿⼀天只能赛⼀次;循环赛⼀共进⾏n-1天。

按此要求设计⼀张⽐赛⽇程表,该表有n⾏和n-1列,第i⾏第j列表⽰第i个选⼿第j天遇到的选⼿。

分析:本题的⽅法有很多,递归是其中⼀种⽐较容易理解的⽅法。

如下图所⽰是k=3时的⼀个可⾏解(第1列是选⼿编号),它是4块拼起来的。

左上⾓是k=2时的⼀组解,左下⾓是左上⾓每个数加4得到,⽽右上⾓、右下⾓分别由左下⾓、左上⾓复制得到。

递归,每⼀次分为4个区域来处理。

当然,也可以根据上⾯分析的规律直接模拟填充数组即可。

循环k-1次,每⼀次填充除了左上⾓之外的另外3个区域。

代码参考:递归的划分过程可以参考残缺棋盘的划分过程。

下⾯是循环填充的代码1 #include <stdio.h>2#define MAX 1013//问题表⽰4int k; //求解结果表⽰5int a[MAX][MAX]; //存放⽐赛⽇程表(⾏列下标为0的元素不⽤)6void Plan(int k)7 { int i,j,n,t,temp;8 n=2; //n从2^1=2开始9 a[1][1]=1; a[1][2]=2; //求解2个选⼿⽐赛⽇程,得到左上⾓元素10 a[2][1]=2; a[2][2]=1;11for (t=1;t<k;t++) //迭代处理2^2(t=1)…,2^k(t=k-1)个选⼿12 {13 temp=n; //temp=2^t14 n=n*2; //n=2^(t+1)15for(i=temp+1;i<=n;i++ ) //填左下⾓元素16for(j=1;j<=temp;j++)17 a[i][j]=a[i-temp][j]+temp;18for(i=1;i<=temp;i++)//填右上⾓元素19for(j=temp+1;j<=n;j++)20 a[i][j]=a[i+temp][(j+temp)%n];21for(i=temp+1;i<=n;i++)//填右下⾓元素22for(j=temp+1;j<=n; j++)23 a[i][j]=a[i-temp][j-temp];24 }25 }26int main()27 {28 Plan(3);29for(int i=1;i<=3;i++)30 {31for(int j=1;j<=3;j++)32 printf("%d ",a[i][j]);33 printf("\n");34 }35return0;36 }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学年论文题目循环赛日程表问题研究学生指导教师年级2009级专业软件工程系别软件工程学院计算机科学与信息工程学院哈尔滨师范大学2012年6月论文提要本文采用分治算法来解决循环赛日程表的安排问题。

通过对问题的详细分析,列出1到10个选手的比赛日程表,找出两条规则,作为算法实现的依据,而后采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

同时也介绍了循环赛日程表问题的另一种解法多边形解法,这种方法另辟蹊径,巧妙地解决了循环赛日程表问题,运行效率较高。

循环赛日程表问题研究摘要:本文采用分治算法来解决循环赛日程表的安排问题。

根据算法的设计结果,采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

同时也介绍了循环赛日程表问题的另一种解法,这种方法另辟蹊径,想法独特,运行效率较高。

关键词:循环赛日程表问题;分治法一、题目描述设有n 个运动员要进行网球循环赛。

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

当n 是奇数时,循环赛进行n 天。

二、问题分析循环赛日程表可以采用分治法实现,把一个表格分成4个小表格来处理,每个小表格都是一样的处理方法,只是参数不同。

分析过程具体如下:1、n=1(表2-1)2.、n=2(表2-2)3、n=3(1) 添加一个虚拟选手4#,构成n+1=4(2) 4/2=2,分两组,每组各自安排(1 2),(3 4) (3) 每组跟另一组分别比赛(拷贝)这是四个人比赛的(表2-3) 4人赛程(4) 把虚选手置为0 (表2-4)3人赛程这是三个人比赛的安排4、n=4,见表2-35、n=5(1) 加一个虚选手,n+1=6。

安排好6个人的比赛后,把第6个人用0表示即得5人的。

(2) 分成两组(1 2 3) (4 5 6),各3名选手(3) 依照表2-4,安排第1组;按表2-5安排第2组(除0元素外,都加3)(表2-5)(4) 把表2-5排于表2-4下方(表2-6)(5) 把同一天都有空的两组安排在一起比赛(按这种安排,肯定每天只有一对空组)。

(6) 第一组的(1 2 3)和第2组的(4 5 6)分别比赛。

但是由于(1,4), (2, 5), (3 6)已经比赛过了,所以在后面的安排中不能再安排他们比赛。

1 2 34 5 6首先,1#只能和5#或6#比赛。

(a) 若1#-5#,由于3#和6#已经比赛过,所以只能安排: 2#-6#,3#-4#(b) 若1#-6#,由于2#和5#已经比赛过,只能安排:2#-4#,3#-5#这样安排后前三行的后两列,后三行的后两列由上面的三行来定:表2-8就是6名选手的比赛日程安排。

将其中的6号作为虚拟选手,把6换成0,即得5名选手的赛程安排表:(表2-9)5人赛程6、n=6,见表2-8。

7、n=7, 添加1,n+1=8。

8名选手的安排,由4名选手(表2-3)构成(表2-10)8人赛程将其中的8改成0,即得7名选手的赛程安排。

(表2-11)7人赛程8、n=8 ,见表2-10。

9、n=9,由n+1=10人,将虚选手10号置为0来得到。

10、n=10。

10人的比赛,分两组(1 2 3 4 5)和(6 7 8 9 10)各5人。

前5人比赛的安排如表2-12(表2-12)第2组的5人比赛就是将前5人比赛选手(非0)号对应加5(表2-13)然后两组合并,得到表2-14(表2-14)找两组中同一天中没有安排比赛的,安排他们比赛:(表2-15)由于两组中:1 2 3 4 56 7 8 9 10按列对应的已经比赛过一次:1-6,2-7,3-8,4-9,5-10。

后面再安排两组选手分别比赛的时候,就不考虑已经比赛过的组合。

安排两组选手分别比赛的时候,依照这样的规则:1#按递增顺序依次跟没有比赛过的第2组选手比赛(7,8,9,10各一天)。

若1#和x1比赛,则2号从6~10号中从x1之后开始按增序中找第一个没有比赛过的选手,跟他比赛(如果x1=10,则2号从6号开始按增序找)。

3、4、5号也如此找。

结果如表2-16所示:(表2-16)10人的赛程安排观察表2-16的右上角,发现如下规律(表2-8,6人比赛时,也有此规律):【规则一】:每一行数值从左到右循环递增;每一列上也是6~10(即n/2+1~n)循环递增(取到最大值10之后,下一个数字又从6开始取值;而且不包含左上角的块同一行中取过的值)。

第一行第m+1(下标从0开始)列的值为(m+1)+1,依次向右递增;要先处理。

其他行上的值要依赖于它的这个取值。

【规则二】:右下角的块:因为比赛是两两之间进行的,所以右下角由右上角决定(比赛的对手是两个人,因此对应的安排要成对);OK,至此,问题就好解决了,只要按照这个规律填数字,就可以得到一种合理的安排。

由于我们不是求全部的安排,所以,只要得到这么一个解就可以了。

9人比赛,则将表2-16中的10全部用0代替即得。

(表2-17)9人的赛程安排三、算法设计n名选手的赛程安排问题:1、如果n为偶数,可分为两个n/2人的组,分别比赛,然后两组间比赛。

(1)如果n/2为偶数,左下角为左上角加n/2来得到,然后左下角拷贝到右上角;左上角拷贝到右下角;(2)如果n/2为奇数,先安排左下角(除0外都加n/2),然后把同一天都有空的选手安排比赛。

然后,右上角要按规则一来完成,右下角由规则二来定。

2、如果n为奇数,则加1个选手使n+1成为偶数。

转化成偶数名选手的赛程安排问题来解决。

最后把虚拟选手n+1号所在位置上的值置为0。

即完成安排。

四、算法改进循环赛要求比赛的每两个选手都要进行一次比赛,而且每个选手每天都要比赛一场。

这种题目的解法通常是用分治的思想来做,并且是分治方法解题的经典题目。

下面的一种受多边形启发的方法,也能巧妙解决循环赛日程表问题。

多边形解法:有n个选手要进行循环赛,画n边形,每个点表示一个选手。

在同一水平线上的选手进行比赛。

每天的比赛由旋转一次的多边形决定,每次顺时针旋转360/n度。

例如:(1)采用分治法实现代码(c语言实现):/* 循环赛日程安排问题-采用分治法 */#include<stdlib.h>#include<stdio.h>int **A; //int *指针数组,int *schedule; //int数组,一维数组保存二维数组的数据int N =1; //问题的规模。

初始化时会设定//isodd:判断x是否奇数,是则返回1,否则0int isodd(int x){return x&1;}//print:打印赛程void print(){int i,j, row, col;if(isodd(N)){row=N;col=N+1;}else{row=N;col=N;}printf("第1列是选手编号\n");for(i=0;i<row; i++){for(j=0;j<col; j++){printf("%4d", A[i][j]);}printf("\n");}}/*init:初始化,设置问题规模N值,分配内存,用schedule指向;把A构造成一个二维数组*/void init(){ int i, n;char line[100]={'\0'};printf("请输入选手人数:");fgets(line,sizeof(line), stdin);N=atoi(line);if(N<=0) exit(-1);if(isodd(N))n=N+1;elsen=N;//schedule是行化的二维数组schedule=(int *)calloc(n*n, sizeof(int));A=(int **)calloc(n, sizeof(int *));if(!schedule || A==NULL) exit(-2);for(i=0;i<n;i++) //把A等价为二维数组{A[i]=schedule+i*n;A[i][0]=i+1;//初始化这个数组的第一列}return;}/*replaceVirtual:把第m号虚的选手去掉(换做0)*/void replaceVirtual(int m){int i,j;for(i=0;i<m-1;i++) //行:对应选手号1~m-1{for (j=0;j<=m;j++) //列: 比行要多1A[i][j] = (A[i][j]==m)?0:A[i][j];}return;}/*copyeven:m为偶数时用,由前1组的m位选手的安排,来构成第2组m位选手的赛程安排,以及两组之间的比赛安排 */void copyeven(int m){if(isodd(m)) return;int i,j;for (j=0;j<m;j++) //1. 求第2组的安排(+m){for (i=0;i<m;i++){A[i+m][j]=A[i][j]+m;}}for (j=m;j<2*m;j++)//两组间比赛的安排{for (i=0;i<m;i++) //2. 第1组和第2组{A[i][j]=A[i+m][j-m]; //把左下角拷贝到右上角}for (i=m;i<2*m;i++) //3. 对应的,第2组和第1组{A[i][j]=A[i-m][j-m]; //把左上角拷贝到右下角}}return;}/*copyodd:m为奇数时用,由前1组的m位选手的安排,来构成第2组m位选手的赛程安排,以及两组之间的比赛安排。

这时和m为偶数时的处理有区别。

*/void copyodd(int m){int i,j;for (j=0;j<=m;j++) //1. 求第2组的安排(前m天){for (i=0;i<m;i++)//行{if (A[i][j]!=0){A[i+m][j]=A[i][j]+m;}else //特殊处理:两个队各有一名选手有空,安排他们比赛{A[i+m][j] = i+1;A[i][j] = i+m+1;}}}/*安排两组选手之间的比赛(后m-1天)*/for(i=0,j=m+1;j<2*m;j++){A[i][j]= j+1; //2. 1号选手的后m-1天比赛A[ (A[i][j] -1) ][j] = i+1; //3. 他的对手后m-1天的安排}//以下的取值要依赖于1号选手的安排,所以之前先安排1号的赛程for (i=1;i<m;i++) //第1组的其他选手的后m-1天的安排{for (j=m+1;j<2*m;j++){//2. 观察得到的规则一:向下m+1~2*m循环递增A[i][j] = ((A[i-1][j]+1)%m==0)?A[i-1][j]+1 :m + (A[i-1][j]+1)%m;//3. 对应第2组的对手也要做相应的安排A[ (A[i][j]-1) ][j] = i+1;}}return;}/*makecopy:当前有m位(偶数)选手,分成两组,每组由m/2位选手构成由第一组的m/2位选手的安排来构成第二组的比赛安排,第一组与第二组的比赛安排。

相关文档
最新文档