天津工程师范学院
《算法与程序计》
--课程设计报告
班级:计科 0813 班
学号:02210081302
姓名:
设计时间:2009.12.21—12.25
天津工程师范学院
1
一.课程设计名称:
循环赛日程表
二.实验内容
问题描述:
设有 n 位选手参加网球循环赛,n=2^k,循环赛共进行 n-1 天,
每位选手要与其他 n-1 位选手比赛一场,且每位选手每天比赛一场,
不能轮空,按一下要求为比赛安排日程,
(1)每位选手必须与其他 n-1 格选手格赛一场;
(2)每个选手每天只能赛一场;
(3)循环赛一共进行 n-1 天;
请按此要求将比赛日程表设计成有 n 行和 n-1 列的一个表。在表
中的第 i 行和第 j 列处填入第 i 个选手在第 j 天所遇到的选手,其中
1≤i≤n,1≤j≤n-1。
三.实验目的
1.运用分治法,设计解决上述问题的算法,设计出比赛日程表,在表
中的第 i 行和第 j 列处填入第 i 个选手在第 j 天所遇到的选手(其中
1≤i≤n,1≤j≤n-1)。
2.掌握分治算法的应用。
四.算法原理
运用分治法,将原问题划分为较小问题,然后由较小问题的解得出原
问题的解。
天津工程师范学院
2
1.分治法:对于一个规模为 n 的问题,若该问题可以容易的解决(比
如说规模 n 较小),则直接解决,否则将其分解为 k 个规模较小的子
问题,这些子问题相互独立且与原问题形式相同,递归的解决这些子
问题,然后将个子问题的解合并,得到原问题的解。
2.分治法的解题步骤(由三个步骤组成)
划分(divide):将原问题分解为若干个规模较小、相互独立、与
原问题形式相同的子问题。
解决(conquer):若子问题规模较小,则直接求解;否则递归求
解各子问题。
合并(conbine):将各子问题的解合并为原问题的解
五.问题分析
假设 n 位选手顺序编号为 1,2,3……n,比赛的日程表是一个 n
行 n-1 列的表格。i 行 j 列的表格内容是第 i 号选手在第 j 天的比赛
对手。
根据分而治之的原则,可从其中以半选手的比赛日程,导出全体 n 位
选手的的日程,最终细分到只有两位选手的比赛日程出发。
六.设计步骤
1.先设计主函数(main 函数),然后设计两个函数,分别是安排赛事
进行填制表格的函数(void arrangement(int n,int N,int k,int
a[100][100])函数)和输出到屏幕函数(void print(int n,int
a[100][100]))。
天津工程师范学院
3
2.在主函数(main())里调用 void arrangement()函数,对比赛
日程进行安排,根据分而治之原则,绘制比赛日程表格,然后调用
void print()函数,将安排好的比赛日程输出到屏幕上。
七.关键数据结构
1.运用一个二维数组 a[i][j],对安排好的赛事日程进行排列和保存,
并在屏幕上输出。
2.使用二维数组的原因:因为根据题目要求,比赛日程表是一个 n 行
n-1 列的表格,用 a[i][j]代表第 i 号选手在第 j 天遇到的对手,所
以用一个二维数组表示。
八.程序结构
程序主要由三个函数组成:
(1)main()函数(主函数),
(2)void arrangement()函数(本程序的核心函数),
(3)print 函数(输出函数)
1.main()函数
天津工程师范学院
4
main()
int k;
输入 k 值
计算参赛人数 n 值
计算参赛人数 n=2^k
传值
调用 void arrangement()函数
调用 print()函数,输出到
屏幕
结束
天津工程师范学院
5
2.void arrangement()函数
void arrangement(int n,int N,int k,int a[100][100])
m=1
s=1
N
N
N
t++
int i=1
i<=N
Y
i++
i++
a[1][i]=i
s<=k?
Y
N=N/2
int t=1
t<=N?
Y
int i=m+1
i<=2*m
Y
j=m+1
j<=m+1
Y
s++
m=m*2
N
i++
N
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]
j++
结束
6
天津工程师范学院
3.print()函数
void print(int n,int a[100][100])
int i=1
N
i<=n
i++
Y
int j=1
j<=n
N
cout<
九.关键程序功能及其实现的说明
1. .main()函数
(1)函数功能:在屏幕上输入 k 值,计算参赛人数 n,然后调用 void
arrangement()函数和 print()函数。
(2)函数实现:
①先定义一个 k,然后在键盘上输入一个 k 值,并赋值给 k(假设输
入 3);
②运用 for 循环,计算参赛人数 n 的值
for (int i=1;i<=k;i++)
n *= 2;
可得 n=8,即有八个人参赛。
③然后调用 void arrangement()函数和 print()函数,并传值。
2.void arrangement()函数
(1)函数功能:对所有运动员的赛程进行安排,并将其存入数组内。
(2)函数实现:由 main()函数得到 k 值为 3,n 值为 8
①用一个 for 循环输出日程表的第一行
for(int i=1;i<=N;i++)
a[1][i] = i;
1
2
3
4
5
6
7
8
②然后定义一个 m 值,m 初始化为 1,m 用来控制每一次填充表格时 i
(i 表示行)和 j(j 表示列)的起始填充位置。
天津工程师范学院
8