网球循环赛问题

题目如下:

设有n个运动员进行网球循环赛。设计一个满足下列要求的比赛日程表:

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

2)每个选手一天只能赛1

3)当n是偶数时,循环进行n-1天,当n是奇数时,循环赛进行n

 

有两个版本,一个是网上比较通用的一个版本,不过感觉好难理解,还是贴出来吧

代码如下:

/*5	设有n个运动员进行网球循环赛。设计一个满足下列要求的比赛日程表:
(1)每个选手必须与其他n-1个选手比赛一次;
(2)每个选手一天只能赛1次
(3)当n是偶数时,循环进行n-1天,当n是奇数时,循环赛进行n天
*/
#include<stdio.h>
#define N 1000

void fun(int n);
void copy(int n);
void copy1(int n);
void copy2(int n);

int a[N][N],b[N];

void copy(int n)
{
	if(n/2>1&&n/2%2!=0)
		copy1(n);
	else
		copy2(n);

}

void copy1(int n)
{
	int m,i,j;
	m=n/2;
	for(i=0;i<m;i++)
	{
		b[i]=m+i;
		b[m+i]=b[i];
	}
	for(i=0;i<m;i++)
	{
		for(j=0;j<m+1;j++)//由左上角小块的值算出相应的左下角小块的值
		{
			if(a[i][j]>=m)
			{
				a[i][j]=b[i];
				a[m+i][j]=(b[i]+m)%n;
			}
			else
				a[m+i][j]=a[i][j]+m;
		}
		for(j=1;j<m;j++)//由左上角小块的值算出相应的右上角和右下角小块的值
		{
			a[i][m+j]=b[i+j];
			a[b[i+j]][m+j]=i;
		}

	}

}

void copy2(int n)
{
	int i,m,j;
    m=n/2;
    for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			a[i][j+m]=a[i][j]+m;//由左上角小块的值算出对应的右上角小块的值
			a[i+m][j]=a[i][j+m];//由右上角小块的值算出对应的左下角小块的值
			a[i+m][j+m]=a[i][j];//由左上角小块的值算出对应的右下角小块的值

		}
	}
}

void fun(int n)
{
	if(n==1)
	{
		a[0][0]=0;
		return;
	}
	if(n%2==1)
	{
		fun(n+1);
		return;
	}
	fun(n/2);
	copy(n);
}


void main()
{
	int i,num,j;
	printf("参赛队伍数:");
	scanf("%d",&num);
	fun(num);
	if(num%2!=0)
		num++;
	for(i=1;i<num;i++)
	{
		for(j=0;j<num;j++)
		{
			printf("%d ",a[i][j]+1);
		}
		printf("\n");
	}
	printf("注:当n为奇数时代号为n+1的球队,当天轮空!\n");
}


下面一个是我自己做的一个版本

代码如下:

#include<iostream>
#include<vector>
#define M 100
using namespace std;
vector<int > b;
int a[M][M];
int k=0;
void fun(int n);
void prin(int n);
void main()
{
	 int num;
	 printf("please input:");
	 scanf("%d",&num);
	 for(int i=1;i<=num;i++)
		 b.push_back(i);
	 fun(num);
	 for(int j=0;j<k;j++)
	 {
		 for(int h=1;h<=num;h++)
		 {
			 cout<<a[j][h]<<" ";
	 }
		cout<<endl;
	 }
}

void prin(int n)
{ 
	 for(int j=0;j<(n+1)/2-1;j++)
	 {
		a[k][b[j]]=b[n-1-j];
		a[k][b[n-1-j]]=b[j];
	 }
	 if(n%2)
	 {
		a[k][b[(n+1)/2-1]]=0;
	 }
	 else
	 {
		a[k][b[(n+1)/2-1]]=b[(n+1)/2];
		a[k][b[(n+1)/2]]=b[(n+1)/2-1];
	 }
	 k++;
	 b.push_back(b.front());
	 b.erase(b.begin());
}
void fun(int n)
{
	 int m=n;
	 if(n%2)
	 {
		m++;
	 }
	 for(int i=1;i<m;i++)
	 {
		prin(n);
	 }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值