比赛分组(二)——更通用的解法
2016-03-04 18:24
381 查看
两支乒乓球队进行比赛,各出3人,甲队有A、B、C三人,乙队有X、Y、Z三人。
A不跟X比赛,C不跟X或Z比赛。
请问应该如何分组?
思路:
前面用3个嵌套的循环来解决了问题。但是,假如参赛人数多了以后,嵌套的循环太深了。
尝试寻找更通用、简洁的办法——类似N皇后问题的解决思路,递归。
甲组可以依次固定,A先选择乙组的对手;然后B来选对手,A选过的对手不能再选,只需要遍历乙组,发现已经被A选过了,就判断不能选;同样递归到C来选择。
最后再用“A不跟X比赛,C不跟X或Z比赛”的条件过滤,得到最终答案。
#define Team_Len 3
//当前位置npos,判断当前能否选nSelVal序号的对手。从前面0-->(npos-1)已经选了的对手里只要找到当前候选序号,就判断不能选,返回0表示false
int canselect(int Team[], int npos, int nSelVal)
{
int result = 1;
for(int i=0; i<npos; i++)
{
if(Team[i]==nSelVal)
{
result = 0;
break;
}
}
return(result);
}
//递归函数,递归退出条件是到最后一个选择对手
void selectTeamer(int Team[], int nDim, int MaxVal, int npos)
{
if(npos<(nDim-1))
{
//not the last column
for(int val=0; val<=MaxVal; val++)
{
if(canselect(Team, npos, val)) //如果当前对手能够被选择
{
Team[npos]=val;
//还不是最后一个,继续下一个位置选择对手
selectTeamer(Team, nDim, MaxVal, npos+1);
}
}
}
else
{
//当到达最后一个,选择合适的对手,然后得到一个结果,因为前面(n-1)个对手都已经选择好了
for(int val=0; val<=MaxVal; val++)
{
if(canselect(Team, npos, val))
{
Team[npos]=val;
if((Team[0]!=0)&&(Team[2]!=0)&&(Team[2]!=2))
{
for(int i=0; i<Team_Len; i++)
printf("%c vs %c\n", 'A'+i, Team[i]+'X');
}
}
}
}
}
A不跟X比赛,C不跟X或Z比赛。
请问应该如何分组?
思路:
前面用3个嵌套的循环来解决了问题。但是,假如参赛人数多了以后,嵌套的循环太深了。
尝试寻找更通用、简洁的办法——类似N皇后问题的解决思路,递归。
甲组可以依次固定,A先选择乙组的对手;然后B来选对手,A选过的对手不能再选,只需要遍历乙组,发现已经被A选过了,就判断不能选;同样递归到C来选择。
最后再用“A不跟X比赛,C不跟X或Z比赛”的条件过滤,得到最终答案。
#define Team_Len 3
//当前位置npos,判断当前能否选nSelVal序号的对手。从前面0-->(npos-1)已经选了的对手里只要找到当前候选序号,就判断不能选,返回0表示false
int canselect(int Team[], int npos, int nSelVal)
{
int result = 1;
for(int i=0; i<npos; i++)
{
if(Team[i]==nSelVal)
{
result = 0;
break;
}
}
return(result);
}
//递归函数,递归退出条件是到最后一个选择对手
void selectTeamer(int Team[], int nDim, int MaxVal, int npos)
{
if(npos<(nDim-1))
{
//not the last column
for(int val=0; val<=MaxVal; val++)
{
if(canselect(Team, npos, val)) //如果当前对手能够被选择
{
Team[npos]=val;
//还不是最后一个,继续下一个位置选择对手
selectTeamer(Team, nDim, MaxVal, npos+1);
}
}
}
else
{
//当到达最后一个,选择合适的对手,然后得到一个结果,因为前面(n-1)个对手都已经选择好了
for(int val=0; val<=MaxVal; val++)
{
if(canselect(Team, npos, val))
{
Team[npos]=val;
if((Team[0]!=0)&&(Team[2]!=0)&&(Team[2]!=2))
{
for(int i=0; i<Team_Len; i++)
printf("%c vs %c\n", 'A'+i, Team[i]+'X');
}
}
}
}
}
相关文章推荐
- hiho1031 01背包
- c++操作符
- PHP log相关函数
- 当web.config文件放置在共享目录下(UNC),启动IIS会提示有错误信息500.19,伴随有错误代码0x80070003和错误代码0x80070005的解决办法
- golang memory analysis
- [转]为何你的产品 Demo 如此糟糕?因为你太注重产品本身了
- PHP字符串函数
- Android新手入门2016(1)--创建和运行helloworld
- shell 编程笔记
- (十七)状态模式-代码实现
- 历届试题 买不到的数目
- ubuntu 切换python3 和 python2
- linux scp远程拷贝文件及文件夹
- IOS dispatch_once
- 基于webpack搭建前端工程解决方案探索
- 划分树 hdu2665 第k小
- PHP empty、isset、isnull的区别
- 对象迁移表空间引出的三个小问题
- Cooike的基本认识
- 化繁为简的翻译机——解释器模式