设有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;
}