递归分治解循环赛问题

5 篇文章 0 订阅
问题描述:
n=2 k 个运动员进行“ 地表最强 16 ”循环赛,日程满足:
每个选手必须与其他 n-1 个选手比赛一次;
每个选手一天只能赛一次;
循环赛一共进行 n-1 天。
实验要求
输入: n—— 参加循环赛的运动员人数
输出:日程表的详细安排(行:运动员;列:一天;间隔: /t 保存结果(学号 + _ 循环赛” +.txt
程序:分治过程必须通过递归函数 Scheduled( int i , int size) 表达

          其中 i表示目前正在解决的日程表起始位置 size代表需要解决的大小

注:调用过程禁止直接写在主函数中!
因为老师要求特殊,没什么可以参考的程序,便自己研究研究写了一个,基本上自己的算法实验都是晚上在没人的地方研究一晚上便搞出来的。
#include<stdio.h>
#define N 100
int a[N][N];

void Scheduled(int i,int size)
{
	int x,y;
	if(size == 2)// size=2是最小问题,判断是否是最小的终止条件,是就赋值(事实赋值了第一列)
	{
		a[i][1]=i;
		a[i+1][1]=i+1;
		//return;
	}
	else{
		Scheduled(i,size/2);//左上部分的递归完成第一列
		Scheduled(i+size/2,size/2);//左下部分的递归完成第一列
	}

	for(x=i;x<i+size/2;x++)//一次性填充半个子表,上半部分的表格,此右上部分内容完全复制左下部分
		for(y=size/2+1;y<=size;y++){//左右对称进行填充
			a[x][y]=a[x+size/2][y-size/2];//填充表格
			//printf("I am a[%d][%d] is %d\n",x,y,a[x][y]);
		}
	for(x=i+size/2;x<i+size;x++)//此右下部分内容完全复制左上部分
		for(y=size/2+1;y<=size;y++){
			a[x][y]=a[x-size/2][y-size/2];
			//printf("I am a[%d][%d] is %d\n",x,y,a[x][y]);
		}
}

void Print(int n){
	int p,q;
	FILE *fp;
	fp=fopen("e:\\222015325012065_循环赛.txt","wb");
	printf("每行第一列指运动员编号,从第二列起指此运动员在第一天到最后一天要比赛的选手。\n");
	fprintf(fp,"每行第一列指运动员编号,从第二列起指此运动员在第一天到最后一天要比赛的选手。\r\n");
	for(p=1;p<=n;p++){
		for(q=1;q<=n;q++){//第一列为参赛人员
			printf("%d\t",a[p][q]);
			fprintf(fp,"%d\t",a[p][q]);
		}
		printf("\n");
		fprintf(fp,"\r\n");
	}
	fclose(fp);
	printf("e盘的222015325012065_循环赛.txt has been finished!\n");
}


int main(){
	int n;
	printf("Please input the value of n:\n");
	scanf("%d",&n);
	Scheduled(1,n);
	Print(n);
	return 0;	
}


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值