循环赛日程表
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
A可以决定B,B=A+n/2 C=编号较大数,每天循环轮转一次 D=编号较小数,每天循环轮转一次
❖当n/2为分偶治数 法应用 n=偶
与n 情形类似,直接用分治法求解
❖ 当n/2为奇数
递归返回的轮空的比赛要作进一步处理 前n/2轮比赛中让轮空选手与下一个未参赛选手进行比
赛
代码实现
void tourna(int n)
//改进的分治赛算法
{
if(n==1){a[0][0]=0;return;}
解题算法
递归
N=2
分治法步骤
分解
递归
求解
合并
将原问题分解 若干个 规模小
相互独立 形式相同
子问题
再继续分解 为更小的 子问题
容易被解决 则直接解
子问题的解 合并为
原问题的解
分治法步骤
divide-and-conquer(P) { if ( | P | <= n0) adhoc(P); //解决小规模的问题 divide P into smaller subinstances P1,P2,...,Pk;//分解问题 for (i=1,i<=k,i++) yi=divide-and-conquer(Pi); //递归的解各子问 题 return merge(y1,...,yk); //将各子问题的解合并 为原问题的解 }
目录
1. 问 题 描 述 2. 解 题 思 想 3. 代 码 实 现 4.性 能 分 析 4. 调 试 运 行
www.themegallery.com
❖ 题目
问题描述
设计一个满足以下要求的比赛日程表
❖ 具体要求
(1)每个选手必须与其他n-1个选手各赛一次
(2)每个选手一天只能赛一次 (3)循环赛一共进行n-1天
输出要求
有n行和n-1列的表。在表中的第i行,第j列处填入第i个选 手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1
输出要求(n=4时) 有n行和n-1列的表。在表中的第i行,第j列处填
入第i个选手在第j天所遇到的选手。其中1≤i≤n, 1≤j≤n-1
第一天 第二天 第三天
0
1
2
3
1
0
3
2
2
N=8
12345678 21436587 34127856 43218765 56781234 65872143 78563412 87654321
题目分析
N为偶
N为奇
将所有选 手 对分成 为 两组
加入一个 虚拟队员
凡治解众如治题寡,思分数想是也-。-分----治孙子法兵法
N/2
N/4 分治法
//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];
}
//未完
www.themegallery.com
代码实现
for(i=0;i<m;i++){
for(int j=0;j<m+1;j++)
❖输入判断 分治法应用
当n小于或等于1时,没有比赛。 当n是偶数时,至少举行n-1轮比赛. 当n是奇数时,至少举行n轮比赛,这时每轮必有一支
球队轮空。
❖ 统一奇偶性
当n为奇数时,可以加入第n+1支球队(虚拟球队,实 际上不存在),并按n+1支球队参加比赛的情形安排
比赛日程 。
只需要考虑输入为偶数
if(odd(n)){tourna(n+1);return;} //n为奇
tourna(n/2);
//n为偶数,分治
makecopy(n);
//合并
}
代码实现
void makecopy(int n) //合并算法 { if((n/2)>1&&odd(n/2)) copyodd(n);
时
else copy(n); }
N=5 N=2
N=7 N=8
www.themegallery.com
N=2
N=3
N=4
N=7
N=8
{//由左上角小块的值算出相应的左下角小块
if(a[i][j]>=m)
{
a[i][j]=b[i];
a[m+i][j]=(b[i]+m)%n;
}
else a[m+i][j]=a[i][j]+m;
www.themegallery.com
代码实现
//由左上角小块的值算出相应的右上角和右下角 小块的 for(j=1;j<m;j++) { a[i][m+j]=b[i+j]; a[b[i+j]][m+j]=i; } }
}
时间复杂度分析
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),
www.themegallery.com
调试运行
N=4 N=3