循环赛日程表
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
循环赛日程表安排
N=2k个运动员进行网球循环赛。 设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次; (2)每个选手一天只能赛一次; (3)循环赛一共进行n-1天。
填补法
用一张二维表示日程表,以a[i-1][j-1]的值表示第i号选手在第j 天的比赛对手
第一天
1号 2 2号 1
while(m>1){m/=2;k++;} //求log2(n)
for(i=1; i<=n; i++) a[1][i]=i;//设置日程表第一行
m = 1;//每次填充时,起始填充位置 for(s=1; s<=k; s++)//填充块大小为4,16,64。。。的块 {
n /= 2; for( t=1; t<=n; t++)//填充块的个数 {
} } m *= 2; } }
for( i=m+1; i<=2*m; i++)//控制行 {
for( 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];//左下角等于右上角的值 }
网上的分治法
辅助
1天
2天
3天
1号
1
2
3
4Hale Waihona Puke Baidu
2号
2
1
4
3
3号
3
3
1
2
4号
4
4
2
1
辅助 1天
2天
3天
4天
5天
6天
7天
1号
1
2
3
4
5
6
7
8
2号
2
1
4
3
6
5
8
7
3号
3
4
1
2
7
8
5
6
4号
4
3
2
1
8
7
6
5
5号
5
6
7
8
1
2
3
4
6号
6
5
8
7
2
1
4
3
7号
7
8
5
6
3
4
1
2
8号
8
7
6
5
4
3
2
1
void Table(int n) { int i,j,s,t,m=n, k = 0;
n=2
第一天
1号 2
第二天
3
第三天
4
2号 1
4
3
3号 4
1
2
4号 3 2 1
n=4
void Table(int k)
{
if(k == 2)//只有两个人的时候,可以很简单安排 { a[0][0] = 2; a[1][0] = 1; } else//如果不是两个人的安排,那由上一层安排推出 { Table(k/2);//处理完上一层安排后,用上一层的安排填补空白处 copyToLB(k/2);//填补左下角 copyToRT(k/2);//填补右上角 copyToRB(k/2);//填补右下角 } }
旋转法
先把n(8)为选手的编号存入一个长度为n(8)的一维数组里
1
2
3
4
5
6
7
8
队
列
枢
头
1场 2场 3场 4场
轴
1天
8-5 4-6 3-7 2-1
2天
8-6 5-7 4-1 3-2
3天
4天
5天
6天
7天
具体实现: for(i=0;i<n-1;i++) //1到n-1号旋转i次 {
printf("第%d天: ",i+1); printf("%d - %d ",a[n-1],a[(zhou+i)%(n-1)]);//最后一个和中轴 for( j=1;j<n/2;j++) {//离中轴距离相等的两个 printf("%d - %d ",a[(zhou-j+i)%(n-1)],a[(zhou+j+i)%(n-1)]); } printf("\n"); }
N=2k个运动员进行网球循环赛。 设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次; (2)每个选手一天只能赛一次; (3)循环赛一共进行n-1天。
填补法
用一张二维表示日程表,以a[i-1][j-1]的值表示第i号选手在第j 天的比赛对手
第一天
1号 2 2号 1
while(m>1){m/=2;k++;} //求log2(n)
for(i=1; i<=n; i++) a[1][i]=i;//设置日程表第一行
m = 1;//每次填充时,起始填充位置 for(s=1; s<=k; s++)//填充块大小为4,16,64。。。的块 {
n /= 2; for( t=1; t<=n; t++)//填充块的个数 {
} } m *= 2; } }
for( i=m+1; i<=2*m; i++)//控制行 {
for( 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];//左下角等于右上角的值 }
网上的分治法
辅助
1天
2天
3天
1号
1
2
3
4Hale Waihona Puke Baidu
2号
2
1
4
3
3号
3
3
1
2
4号
4
4
2
1
辅助 1天
2天
3天
4天
5天
6天
7天
1号
1
2
3
4
5
6
7
8
2号
2
1
4
3
6
5
8
7
3号
3
4
1
2
7
8
5
6
4号
4
3
2
1
8
7
6
5
5号
5
6
7
8
1
2
3
4
6号
6
5
8
7
2
1
4
3
7号
7
8
5
6
3
4
1
2
8号
8
7
6
5
4
3
2
1
void Table(int n) { int i,j,s,t,m=n, k = 0;
n=2
第一天
1号 2
第二天
3
第三天
4
2号 1
4
3
3号 4
1
2
4号 3 2 1
n=4
void Table(int k)
{
if(k == 2)//只有两个人的时候,可以很简单安排 { a[0][0] = 2; a[1][0] = 1; } else//如果不是两个人的安排,那由上一层安排推出 { Table(k/2);//处理完上一层安排后,用上一层的安排填补空白处 copyToLB(k/2);//填补左下角 copyToRT(k/2);//填补右上角 copyToRB(k/2);//填补右下角 } }
旋转法
先把n(8)为选手的编号存入一个长度为n(8)的一维数组里
1
2
3
4
5
6
7
8
队
列
枢
头
1场 2场 3场 4场
轴
1天
8-5 4-6 3-7 2-1
2天
8-6 5-7 4-1 3-2
3天
4天
5天
6天
7天
具体实现: for(i=0;i<n-1;i++) //1到n-1号旋转i次 {
printf("第%d天: ",i+1); printf("%d - %d ",a[n-1],a[(zhou+i)%(n-1)]);//最后一个和中轴 for( j=1;j<n/2;j++) {//离中轴距离相等的两个 printf("%d - %d ",a[(zhou-j+i)%(n-1)],a[(zhou+j+i)%(n-1)]); } printf("\n"); }