比赛分组(二)——更通用的解法

     两支乒乓球队进行比赛,各出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');
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值