算法分析:锦标赛问题 分治算法

【问题描述】设有n=24个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:

(1)每个选手必须与其他n-1个选手各赛一次;

(2)每个选手一天只能参赛一次;

(3)循环赛在n-1天内结束。

请按此要求将比赛日程表设计成有n行和n-1列的一个表。在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。编写程序,输出k=4时的比赛日常表(矩阵)。

 [实验提示]

我们可以按分治策略将所有的选手分为两半,则n个选手的比赛日程表可以通过n/2个选手的比赛日程表来决定。递归地用这种一分为二的策略对选手进行划分,直到只剩下两个选手时,比赛日程表的制定就变得很简单。这时只要让这两个选手进行比赛就可以了。

1

2

3

4

5

6

7

1

2

3

4

5

6

7

8

2

1

4

3

6

5

8

7

3

4

1

2

7

8

5

6

1

2

3

4

3

2

1

8

7

6

5

1

2

3

4

5

6

7

8

1

2

3

4

1

2

1

4

3

6

5

8

7

2

1

4

3

1

2

3

4

1

2

7

8

5

6

3

4

1

2

2

1

4

3

2

1

8

7

6

5

4

3

2

1

(1)                                               (2)                                                             (3)

图1  2个、4个和8个选手的比赛日程表

 [实验步骤]

采用递归方式设计并实现算法并准备测试用例,修改并调试程序,直至正确为止;

应用设计的算法和程序求锦标赛问题;

去掉测试程序,将你的程序整理成功能模块存盘备用.

算法分析:

        根据相应的分析,我们需要为最开始的n=2的情况进行人工的赋值。之后我们要做的就是扩大这个矩阵的维度,此时n变成4,那么接下来我们就需要依据这个左上角的矩阵的数据,去依次完善左下角,右上角和右下角的矩阵的内容。经过分析发现相应的矩阵中的数值是有规律的,所以可以依次循环赋值即可。

        此时我们根据k的值进行下一次大的循环,此时继续为n进行乘以2处理,然后重复如上的内容即可将该矩阵赋值完成。

代码实现部分:

#include<iostream>
using namespace std;
#define MAX 101 
int k;  
int a[MAX][MAX];
void plan(int k){
	int i,j,n,t,temp;
	n=2;   //k=1的时候 即2的一次方的结果
	a[1][1]=1;a[1][2]=2;a[2][1]=2;a[2][2]=1;
	for(t=1;t<k;t++){
		temp=n;
		n=n*2;
		for(i=temp+1;i<=n;i++)
			for(j=1;j<=temp;j++)
				a[i][j]=a[i-temp][j]+temp;
		for(i=1;i<=temp;i++)
			for(j=temp+1;j<=n;j++)
				a[i][j]=a[i+temp][(j+temp)%n];
		for(i=temp+1;i<=n;i++)
			for(j=temp+1;j<=n;j++)
				a[i][j]=a[i-temp][j-temp];
	} 
} 
int main(){
	cout<<"please input the k:";
	cin>>k;
	plan(k);
	int i,j,res=1;
	for(i=1;i<=k;i++)
		res*=2;
	for(i=1;i<=res;i++)
		for(j=1;j<=res;j++){
			cout<<a[i][j]<<" ";
			if(j==res)
				cout<<endl;
		}
	return 0;
}

实验结果:

 

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Simon_Smith

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值