循环赛问题(递归,分治)

题目描述

设有n个选手的网球循环比赛,其中n=2^k(0≤k<7)。现要设计一个满足以下条件的比赛日程表:
(1)每名选手要与其他n−1名选手都进行一次比赛;
(2)每名选手每天只赛一次;
(3)整个比赛共进行n−1天,要求每天没有选手轮空。

输入描述

选手人数n(n≤100),n只能为2的整数次幂。

输出描述

N阶方阵A[1..n,0..n−1],当j>0时,A[i,j]表示第i名运动员在第j天所遇到的比赛对手(A[i,0]=i),每个数据占5位宽度。

输入

4

输出 

    1    2    3    4
    2    1    4    3
    3    4    1    2
    4    3    2    1

历时三天,终于解决。放弃循环,苦想递归!(难道循环难吗,不难,只是阻挡我装伯夷的步伐


//分析:
/*
    通过观察题目很容易看出,这是一道分治思想的题目
    那就不得不用递归来想一下了
    把整个图看成一个坐标系的四个象限
      ① | ②
     —— + ——
      ③ | ④
    所以我们要做的是借助拷贝函数进行数据的传递:
        ①->④    ②->③
    但是我们只有第一行的数据,这就需要我们把整个问题细分成无数个小部分
    这里就用到了我们的分割函数。
    所以我们先割后拷
    这样就可以得出答案了
*/

#include<bits/stdc++.h>
using namespace std;

int a[101][101];
int n;

void copy(int x,int y,int cx,int cy,int form) {//拷贝函数
	//x y 初始位置
	//cx cy 目标位置
	//form 规模
	for(int i=0; i<form; i++)
		for(int j=0; j<form; j++)
			a[cx+i][cy+j]=a[x+i][y+j];
}
void part(int form,int x,int y) {//分割函数
	if(form==1)
		return;
	int t=form>>1;
	part(t,x,y);//先割后拷
	part(t,x,y+t);
	copy(x,y,x+t,y+t,t);
	copy(x,y+t,x+t,y,t);
}

int main() {
	cin>>n;
	for(int i=1; i<=n; i++)
		a[1][i]=i;
	part(n,1,1);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++)
			printf("%5d",a[i][j]);
		cout<<"\n";
	}
	return 0;
}

//CSDN:panjyash原创 拒绝转载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

panjyash

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

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

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

打赏作者

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

抵扣说明:

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

余额充值