BJFU_计算机算法设计与实践_作业2

本文探讨了2^k个运动员网球循环赛的日程表设计,提出并分析了三种算法:迭代法(算法1)、递归法1(算法2)和递归法2(算法3)。所有算法均满足每名选手与其他选手各赛一次且每天仅赛一场,时间复杂度均为O(4^k)。总结指出,算法1在时间上最优,算法2在可读性与简洁性之间取得平衡,而算法3由于递归导致效率较低。
摘要由CSDN通过智能技术生成

作业2

问题描述

编写程序实现循环赛日程表。设有n=2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其它n-1个选手各赛一次
(2)每个选手一天只能赛一场
(3)循环赛进行n-1天

问题思路

假设n位选手被顺序编号为1、2、…、n(2^k)。可将比赛日程表设计成一个n行n-1列的二维数组,其中第i+1行、第j+1列表示和第i个选手在第j天比赛的选手号。观察可知,数组均分四块后,其左上角等于右下角,左下角等于右上角。只要求出左上角和左下角的解,就能得出其余部分的解。
故采用分治法,将一个难以直接解决的大问题划分成一些规模较小的相同问题,便于各个击破。在此基础上,我写了3种算法。
(1)算法1:改写课件代码,采取自底向上的迭代。
(2)算法2:算法1的改写,采取自顶向下的递归。
(3)算法3:算法2的改写,仍采用自顶向下递归。

算法1
伪代码描述
1.输入k,总数为2k,a[0][0]=1,t=1
2.循环直到k为0
	2.1 for i=0 to i=t					//左上角的宽度为t
			for j=0 to j=t
				a[i+t][j+t]=a[i][j];	//填充右下角
				a[i+t][j]=a[i][j]+t;	//填充右上角
				a[i][j+t]=a[i][j]+t;	//填充左下角
	2.2 t=t*2							//新的左上角产生,迭代填充
	2.3 k--			
3.输出a
算法时间复杂度分析

T(k)表示2^k个选手循环赛问题的求解时间,T(k)满足如下递推式:
T(k)=1 k=1
T(k)=4T(k-1) k>1
解此递推式可得T(k)=O(4^k)。

C++描述
#include<iostream>
#include<Windows.h>
#include<iomanip>
using namespace std;
void Plan(int a[][256],int k)
{
      
	a[0][0]=1;
	int i,j,t=1;														 
	while(k--)						//k为迭代次数
	{
   
		for(i=0;i<t;i++)			//t表示左上角的a[0][0]到a[t-1][t-1]填充完毕
		{
   
			for(j=0;j<t;j++)		//左上角的宽度为t
			{
   
				a[i+t][j+t]=a[i][j];	//填充右下角
				a[i+t][j]=a[i][j]+t;	//填充右上角
				a[i][j+t]=a[i][j]+t;	//填充左下角
			}
		}
		t=t*2;					//新的左上角产生,接着填充
	}
	cout<<"算法1"<<endl;
	for(i=0;i<t;i++)				//t为总人数,输出数组a
	{
    
		for(j=0;j<t;j++)
		{
   
			cout<<setiosflags(ios::left)<<setw(3)<<a[i][j];
		}
		cout<<endl;
	}
}
int main
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值