每日一题 比赛安排

说明设有2n(n<=6)个球队进行单循环比赛,计划在2 n – 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2n – 1天内每个队都与不同的对手比赛。例如n=2时的比赛安排:    队           1  2                  3  4    比赛       1==2               3==4                一天                  1==3               2==4                二天                         1==4               2==3                三天输入格式每个测试文件只包含一组测试数据,每组输入数据为一个正整数n(n<=6)。输出格式对于每组输入数据,输出比赛安排,从第一天的安排开始,每天占一行,每行开头先输出天号,再输出当天的安排,优先给队伍编号小的队伍安排比赛,具体格式见样例输出。样例输入数据 12输出数据 1<1>1-2,3-4<2>1-3,2-4<3>1-4,2-3

解题思路:\n\n【1】用二维数组的索引位置表示队员的标号,待安排的队员数组的数值为置为1,其他都置为0;那么接下来要安排的就是那些二维数组数值为1的索引位置(用i和j表示第i个队员和第j个队员将可能发生一场比赛)。\n【2】先定下第i以及第j个队员(通过if(a[i][j]==1)来判定),然后暂时(注意这里是暂时排出因为下一天的场次比赛还需要还需要用)排出掉第i行,第j行,第i列,第j列(目的是为了安排不同的队员,不重复进行比赛),排除的方法就是将a[i][j]=3;改变二维数组值。接着安排同一天的下一场比赛信息(谁和谁比赛)。

#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int a[65][65]; //为1时表示,可以被安排,为2时表示已经被安排过了 ,为3表示暂时被排除 
int n;
int ans[100];
int k=1;//ans数组的索引位置的初始值 
int cnt=0;//第几天 
void f(int step)//step==pow(2,n-1)+1时,输出结果 
{
    //输出结果
    int h=(int)pow(2,n)-1;//行数 最大值 
    int l=(int)pow(2,n);//列数最大值 
    int i,j,ii,jj; 
    if(step==(int)pow(2,n-1)+1) //符合输出条件 
    {
        cnt++;
        cout<<"<"<<cnt<<">";
        for(i=1;i<k;i+=2)//第i和第j个队员的标号都存储在ans数组中,奇数存储第i个队员,偶数是第j 
        {
            if(i==k-2)
            cout<<ans[i]<<"-"<<ans[i+1]<<endl;
            else
            cout<<ans[i]<<"-"<<ans[i+1]<<" ";
        }
        for(i=1;i<=h;i++)
            for(j=i+1;j<=l;j++)
                if(a[i][j]==3)//将上一天中的标记为暂时被排除的队员标号(索引位置)恢复 
                    a[i][j]=1;
        k=1;//将数组ans的索引位置置为1表示重新更新ans数组的值,即下一天的场次信息 
        f(1);//从下一天的第一场开始安排(注意这里容易出错,不要忘记了这句代码) 
    }
    else
    {
        for(i=1;i<=h;i++)
        {
             for(j=i+1;j<=l;j++)
            {
                if(a[i][j]==1) //可以被安排,之后 
                {
                    a[i][j]=2;//第i个队员和第j个队员已经确定好被安排场次啦 
                    for(ii=1;ii<=h;ii++)
                        for(jj=ii+1;jj<=l;jj++)
                        {
                            if((ii==i||ii==j||jj==i||jj==j)&&a[ii][jj]==1)
                                a[ii][jj]=3;
                        }
                    ans[k++]=i;
                    ans[k++]=j;    
                    //cout<<i<<" "<<j<<",";    
                    f(step+1);//安排下一场次的比赛队员信息(标号) 
                } 
            }
        } 
    }
}
int main()
{
    cin>>n;
    int i,j;
    int h=(int)pow(2,n)-1;
    int l=(int)pow(2,n);
    //cout<<h<<" "<<l<<endl;
    for(i=1;i<=h;i++)
        for(j=i+1;j<=l;j++)
            a[i][j]=1;//记录有可能发生比赛的第i个球队和第j个球队的综合情况
            
    f(1);         
    return 0;
}
 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值