【鸽子木 · 每日一题】比赛安排(3月28日)

题目意思比较好理解,同时数据范围不大,不容易超数组和超时,模拟一下题目就可以写。

主要是要搞懂题目的算法

模拟:以n=2为例。

第一天:优先1-2进行比赛,每队每天只能比赛一次,比赛后,当天1和2都不能比赛。

第二天:1和2恢复比赛,但不允许对抗。则依然是1先比赛,那么1不可以和2对抗,就优先小号先比赛,则是1-3,对抗之后只剩2和4,不过从另一方面来讲也必须优先2比赛,因为除了1-3,最小的就是2。那么2必须和最小的(仅剩的)4比赛,则是1-3,2-4.

第三天:依然优先1比赛,但是1-2、1-3都被禁止了,那么就是1-4进行比赛,2-3自然就是一队。

#include<bits/stdc++.h>
using namespace std;
int ans[70][70];
int n; 
int test[70][70];
int used[70][70];
//for统一使用(i=1;i<= N;i++)格式 
int main() 
{

	scanf("%d",&n);
	int N = pow(2,n);
	//刷一遍第一列和第二列
	for(int i = 1 ; i <= N - 1 ; i++)
	{
		ans[i][1] = 1;
		ans[i][2] = i+1;	
		used[i][ans[i][2]] = 1;
		test[ans[i][1]][ans[i][2]] = 1;	
		test[ans[i][2]][ans[i][1]] = 1;	
	} 
	
	for(int i = 1 ; i <= N ; i++) ans[1][i] = i;

	for(int i = 1 ; i <= N ; i+=2)
	{
		test[ans[1][i]][ans[1][i+1]] = 1;		
		test[ans[1][i+1]][ans[1][i]] = 1;	
	} 
	//开始
	for(int day = 2 ; day <= N - 1 ; day++)
	{
		for(int j = 3 ; j <= N ; j++)
		{
			if(j%2==1)//第一列 
			{
				for(int k = 2 ; k <= N ; k++)
				{
					if(used[day][k] == 0)
					{
						ans[day][j] = k;
						used[day][k] = 1;
						break;
					}
				}
			}
			else if(j%2==0)//第二列 
			{
				for(int k = 3 ; k <= N ; k++)
				{
					if(used[day][k] == 0)
					{
						if(test[ans[day][j-1]][k] == 0 && test[k][ans[day][j-1]] == 0)
						{
							ans[day][j] = k;
							used[day][k] = 1;
							test[ans[day][j-1]][k] = 1;
							test[k][ans[day][j-1]] = 1;
							break;
						}	
					}
				}
			}
		}
	} 
	
	//test_test
//	for(int i = 1 ; i <= N; i++)
//	{	
//		for(int j = 1 ; j <= N ; j++)
//		{
//			cout << test[i][j] << " ";
//		}
//		cout << endl;
//	} 
	
	//ans_test
	for(int i = 1 ; i <= N - 1 ; i++)
	{	
		printf("<%d>",i);
		for(int j = 1 ; j <= N ; j++)
		{
			if(j == N) printf("%d",ans[i][j]);
			else if(j%2 == 0) printf("%d,",ans[i][j]);		
			else if(j%2 == 1) printf("%d-",ans[i][j]);	
		}
		printf("\n");
	} 
	

	return 0;
}

这串题解引入了几个数组,我用来储存数据

ans[][]用来储存最后的答案,实际上最后是二维数组输出的。

下面几个实际上可以用一维数组,每天重新刷新即可,但是我觉得二维数组比较方便。

used[day][num]用来储存第day天中,从小到大遍历哪个队伍比过了,比过了就赋值=1,没比过就可以通过,进行下一步判断

下一步判断,x-y两队曾经有没有打过比赛,所以引入test[][],这里的坐标直接表示队伍代码,例如1和2比过,则test[1][2]=1,我不确定test[2][1]有没有必要赋值(懒得试),但本质上是一样的,只要保证这两队互相比过就行了。

这个有一个细节:

第一列永远是1

第二列永远是1 2 3 4 5……

第一行永远是1 2 3 4 5……

所以前期直接刷一遍数据就行,就不需要重复判断这个范围了。

如果要这么做就需要提前储存一下used和test的数据,不然后面就是bug(找了一会儿)

虽然这个嵌套比较长,但是总体来说只要思路清晰就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值