比赛安排(每日一题)

题目

设有2n(n<=6)个球队进行单循环比赛,计划在2 n – 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2n – 1天内每个队都与不同的对手比赛。

例如n=2时的比赛安排:

队 1 2 3 4

比赛 12 34 一天

​ 13 24 二天

​ 14 23 三天

输入格式

每个测试文件只包含一组测试数据,每组输入数据为一个正整数n(n<=6)。

输出格式

对于每组输入数据,输出比赛安排,从第一天的安排开始,每天占一行,每行开头先输出天号,再输出当天的安排,优先给队伍编号小的队伍安排比赛,具体格式见样例输出。

样例
输入

2

输出

<1>1-2,3-4
<2>1-3,2-4
<3>1-4,2-3

解题思路

用f数值标记每个队伍的比赛情况,vis数组标记一天的比赛情况,

三层循环去依次比较比赛的情况 ,

第一层 枚举天数 第二层枚举比赛队伍 第三层枚举上一层的对手。

可以先试试在纸上来写,拿n=3为例,即有8只队伍比赛7天

先看第一天1可以和2,3可以和4,5可以和6,7可以和8

第二天1已经和2比赛过了,所以安排1和3,再接着看2,往后遍历,因为3已经安排和1比赛了,所以2只能和4,5的情况和仿照1的情况所以5-7,6-8。

因此穷举的过程可以得到了,第一重循环跑2^n-1天,第二重循环从小到大跑队伍,第三重循环跑当前队伍的对手,全局上需要开一个二维数组记录哪两个队伍已经比赛过了,在每一天里面,需要开一个一维数组记录在这一天,该队伍是不是已经被安排了。

代码

#include<iostream>
#include<cmath> 
using namespace std;
bool f[70][70]={0};//记录j,k队伍比赛的情况 

int main()
{
	int n;
	cin>> n;
	for(int i=1;i<=pow(2,n)-1;i++)//天数
	{	
		bool vis[70]={0};//下一天就重置一天队伍的比赛状态(标记是否比赛了) 
		cout<< "<"<< i<<">" ;
		int tep=0;//控制逗号的输出
		 
		for(int j=1;j<=pow(2,n);j++)//队伍 
		{	
			if(vis[j]==1) continue;//第j个队伍比过赛就跳过
			vis[j]=1;//没有就标记为安排过了  
			
			for(int k=j+1;k<=pow(2,n);k++)//安排j队伍的对手 
			{
				if(vis[k]==0&&f[j][k]==0) //k在当天没有安排 且j,k没有是过对手 
					{
						vis[k]=1;
				 		f[j][k]=1;
				 		if(tep++)	cout<< ",";//第一次是0所以不会输出,在判断了有队伍比赛的时候 下一次就会输出逗号 
						cout<< j<<"-"<<k;
						break ;//安排完 就退出寻找下一个 
					}
				
			}
		}
		cout<< endl ;
	 } 
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值