关于比赛安排的求解问题

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

队    1 2  3 4

比赛  1-2  3-4  第一天

1-3  2-4  第二天

1-4  2-3  第三天


该问题用分治法来解决,这个思想没有问题,但我找了很多资料发现都是用数组来保存结果。虽然分析问题时有分治的思想,但在代码的形式中并没有体现出分治的思想,经过自己的研究,写了一下几个程序。

1、不加任何修饰,只体现算法思想的代码如下:

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

void game(int bb1,int be1,int bb2,int be2,int &i)
{
      if((bb1+1)==be1&&(bb2+1)==be2)
      {
          cout<<endl<<++i<<"  day"<<endl;
          cout<<bb1<<"---"<<bb2<<endl;
          cout<<be1<<"---"<<be2<<endl;

          cout<<endl<<++i<<"  day"<<endl;
          cout<<bb1<<"---"<<be2<<endl;
          cout<<bb2<<"---"<<be1<<endl;
      }
      else
      {
          int t = i;
          game(bb1,(bb1+be1)/2,bb2,(bb2+be2)/2,i);
          i = t;
          game((bb1+be1)/2+1,be1,(bb2+be2)/2+1,be2,i);

          t = i;
          game((bb1+be1)/2+1,be1,bb2,(bb2+be2)/2,i);
          i = t;
          game(bb1,(bb1+be1)/2,(bb2+be2)/2+1,be2,i);
      }
}
void gametable(int bb1,int be1,int bb2,int be2,int &i)
{
    cout<<bb1<<"  "<<be1<<"  "<<bb2<<"  "<<be2<<endl;
    if((bb1+1)==be1&&(bb2+1)==be2)
    {
         i=1;
         cout<<endl<<1<<" day"<<endl;
         cout<<bb1<<"---"<<be1<<"  "<<bb2<<"---"<<be2<<endl;

         game(bb1,be1,bb2,be2,i);
    }
    else if((bb1+1)!=be1&&(bb2+1)!=be2)
    {
        gametable(bb1,(bb1+be1)/2,(bb1+be1)/2+1,be1,i);
        gametable(bb2,(bb2+be2)/2,(bb2+be2)/2+1,be2,i);
        game(bb1,be1,bb2,be2,i);
    }

}

int main()
{
    int k;
    cout<<"比赛选手个数为n(n=2^k),请输入参数K(K>0):"<<endl;
    cin>>k;
    int i = 0;
    int num =pow(2,k);
    cout<<num<<endl;
    if(num==2)
    {
        cout<<"1 day"<<endl;
        cout<<"1---2"<<endl;
        return 0;
    }

    int bb1,be1,bb2,be2;
    bb1=1;
    be1=num/2;
    bb2=num/2+1;
    be2=num;

    gametable(bb1,be1,bb2,be2,i);


    return 0;
}

2、按序输出结果的程序如下:

#include <iostream>
#include <vector>
#include <cmath>
#include <map>

using namespace std;

void game(int bb1,int be1,int bb2,int be2,int &i, map<int,multimap<int,int> > &map_game)
{
      if((bb1+1)==be1&&(bb2+1)==be2)
      {        
          map_game[++i];         
          ((map_game.find(i))->second).insert(make_pair(bb1,bb2));         
          ((map_game.find(i))->second).insert(make_pair(be1,be2));
         
          map_game[++i];         
          ((map_game.find(i))->second).insert(make_pair(bb1,be2));       
          ((map_game.find(i))->second).insert(make_pair(bb2,be1));
      }
      else
      {
          int t = i;
          map_game[i];
          game(bb1,(bb1+be1)/2,bb2,(bb2+be2)/2,i,map_game);
          i = t;
          game((bb1+be1)/2+1,be1,(bb2+be2)/2+1,be2,i,map_game);

          t = i;
          map_game[i];
          game((bb1+be1)/2+1,be1,bb2,(bb2+be2)/2,i,map_game);
          i = t;
          game(bb1,(bb1+be1)/2,(bb2+be2)/2+1,be2,i,map_game);

      }
}
void gametable(int bb1,int be1,int bb2,int be2,int &i, map<int,multimap<int,int> > &map_game)
{
    if((bb1+1)==be1&&(bb2+1)==be2)
    {
         i=1;      
         map_game[i];
         ((map_game.find(i))->second).insert(make_pair(bb1,be1));
         ((map_game.find(i))->second).insert(make_pair(bb2,be2));

         game(bb1,be1,bb2,be2,i,map_game);
    }

    else if((bb1+1)!=be1&&(bb2+1)!=be2)
    {
        gametable(bb1,(bb1+be1)/2,(bb1+be1)/2+1,be1,i,map_game);
        gametable(bb2,(bb2+be2)/2,(bb2+be2)/2+1,be2,i,map_game);
        game(bb1,be1,bb2,be2,i,map_game);
    }
}

int main()
{
    int k;
    cout<<"比赛选手个数为n(n=2^k),请输入参数K(K>0):"<<endl;
    cin>>k;
    int i = 0;
    //这里最好写一些对k进行检查的代码,确保其为数字且大于零
    int num =pow(2,k);
    cout<<num<<endl;
    if(num==2)
    {
        cout<<"1 day"<<endl;
        cout<<"1---2"<<endl;
        return 0;
    }

    int bb1,be1,bb2,be2;
    bb1=1;
    be1=num/2;
    bb2=num/2+1;
    be2=num;
    map<int,multimap<int,int> > map_game;
    gametable(bb1,be1,bb2,be2,i,map_game);
    map<int,multimap<int,int> >::iterator iter_map = map_game.begin();

    while(iter_map!=map_game.end())
    {       
        cout<<iter_map->first<<" day"<<endl;
        multimap<int,int>::iterator iter_mul = (iter_map->second).begin();
        while(iter_mul!=(iter_map->second).end())
        {
             cout<<iter_mul->first<<"---"<<iter_mul->second<<endl;
             iter_mul++;
        }
        cout<<endl;
        iter_map++;
    }
    return 0;
}


3、可以将结果保存在文本文件中的程序如下

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <map>

using namespace std;

void game(int bb1,int be1,int bb2,int be2,int &i, map<int,multimap<int,int> > &map_game)
{
      if((bb1+1)==be1&&(bb2+1)==be2)
      {
          map_game[++i];
          ((map_game.find(i))->second).insert(make_pair(bb1,bb2));
          ((map_game.find(i))->second).insert(make_pair(be1,be2));

          map_game[++i];
          ((map_game.find(i))->second).insert(make_pair(bb1,be2));
          ((map_game.find(i))->second).insert(make_pair(bb2,be1));
      }
      else
      {
          int t = i;
          map_game[i];
          game(bb1,(bb1+be1)/2,bb2,(bb2+be2)/2,i,map_game);
          i = t;
          game((bb1+be1)/2+1,be1,(bb2+be2)/2+1,be2,i,map_game);

          t = i;
          map_game[i];
          game((bb1+be1)/2+1,be1,bb2,(bb2+be2)/2,i,map_game);
          i = t;
          game(bb1,(bb1+be1)/2,(bb2+be2)/2+1,be2,i,map_game);

      }
}
void gametable(int bb1,int be1,int bb2,int be2,int &i, map<int,multimap<int,int> > &map_game)
{
    if((bb1+1)==be1&&(bb2+1)==be2)
    {
         i=1;
         map_game[i];
         ((map_game.find(i))->second).insert(make_pair(bb1,be1));
         ((map_game.find(i))->second).insert(make_pair(bb2,be2));

         game(bb1,be1,bb2,be2,i,map_game);
    }

    else if((bb1+1)!=be1&&(bb2+1)!=be2)
    {
        gametable(bb1,(bb1+be1)/2,(bb1+be1)/2+1,be1,i,map_game);
        gametable(bb2,(bb2+be2)/2,(bb2+be2)/2+1,be2,i,map_game);
        game(bb1,be1,bb2,be2,i,map_game);
    }
}
int main()
{

    int k;
    cout<<"比赛选手个数为n(n=2^k),请输入参数K(K>0):"<<endl;
    cin>>k;
    int i = 0;
    ofstream output("result.txt",ofstream::out);
    int num =pow(2,k);
    output<<"共有 "<<num<<" 个选手参加比赛,日程安排如下:"<<endl<<endl;
    if(num==2)
    {
        output<<"1 day"<<endl;
        output<<"1---2"<<endl;
        output.close();
        return 0;
    }

    int bb1,be1,bb2,be2;
    bb1=1;
    be1=num/2;
    bb2=num/2+1;
    be2=num;
    map<int,multimap<int,int> > map_game;
    gametable(bb1,be1,bb2,be2,i,map_game);
    map<int,multimap<int,int> >::iterator iter_map = map_game.begin();

    while(iter_map!=map_game.end())
    {

        output<<iter_map->first<<" day"<<endl;

        multimap<int,int>::iterator iter_mul = (iter_map->second).begin();
        while(iter_mul!=(iter_map->second).end())
        {
             output<<iter_mul->first<<"---"<<iter_mul->second<<endl;
             iter_mul++;
        }

        output<<endl;

        iter_map++;
    }
    output.close();

    return 0;
}










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值