蓝桥杯–算法训练 比赛安排
一.比赛题目
1.题目要求
设有有2n(n<=6)个球队进行单循环比赛,计划在2 n – 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2n– 1天内每个队都与不同的对手比赛。
2.输入与输出
输入:
输入文件matchplan.in共一行,输入n的数值。
输出:
输出文件matchplan.out共(2n– 1)行,第i行输出第i天的比赛安排。
格式为: A-B,C-D,……。其中i是天数,A,B分别为比赛双方的编号,每行共2n-1个比赛场次。
输入样例:
2
输出样例:
<1>1-2,3-4
<2>1-3,2-4
<3>1-4,2-3
二.分析过程
枚举+判断
数值很小,可以枚举,利用判断每个球队是否已经在当天比赛过和以前两个队是否比赛过来筛选
1.确定数组
因为需要判断每个球队当天是否比赛过,所以需要一个一维数组a来确定int a[MAXN];
另外还需要判断两只球队是否已经比赛过一次了(单循环),
所以需要一个二维数组来确定int check[MAXN][MAXN];
2.枚举
三重循环:
1)最外层需要从第一天枚举到2n– 1天;
2)中间那层则需要枚举每一个球队;
3)最里面那一层就需要从当前的球队开始一直向后寻找,直到找到相匹配的球队(当天未比赛且未和这只球队比赛的球队)
因为球队有2的n次方个,所以都是两两匹配的,不用担心向后寻找的时候找不到相匹配的球队。
3.判断条件
每天将所有球队的比赛次数设置为0,即将a[MAXN]=0
;
如果第i只球队已经比赛过了就将a[1]=1
;
所以没被比赛过的球队才会进行搜索匹配if(!a[i])
;
同时假如第i只球队已经和第j只球队比赛过了,
那么check[i][j]=1
,因为我们的搜索是向后匹配的,所以并不需要将check[j][i]=1, 不需要check[j][i]=1
所以搜索到后面没被比赛过(这里的没被比赛过是指当天未比赛且没有和第i个球队比赛过)的球队,就代表匹配成功if(!check[i][j]&&!a[j])
三.代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXN 1000
typedef long long ll;
int n,a[MAXN],check[MAXN][MAXN];
//a数组为判断当天是否比赛过
//check数组为判断两只球队是否已经比赛过(单循环)
int main()
{
scanf("%d",&n);
int k=pow(2,n);
//利用pow函数求出2的n次方
for(int i=1;i<k;i++)
{
printf("<%d>",i);
//注意每个前面要输出这种格式的天数
memset(a,0,sizeof(a));
//每天将a数组清0
for(int j=1;j<=k;j++)
{
if(!a[j])
{//当天未比赛,开始向后搜索
int t=j+1;
while(1)
{
if(!check[j][t]&&!a[t])
{//两只球队未进行过比赛
//且当天第t只球队还未比赛过
check[j][t]=1;
printf("%d-%d ",j,t);
break;
}
t++;
}
a[j]=a[t]=1;
//第j只球队和第t只球队都已经比赛过
//都置为1
}
}
printf("\n");
}
return 0;
}