排球队员站位问题+回溯思想

来源:互联网 发布:如何年入百万 知乎 编辑:程序博客网 时间:2024/04/28 14:54

这个题的题意如图所示:



一开始理解起来可能有点困难,但是多看两遍就可以了.......仔细看下题目的每一个要求,这个对解题有很大影响!


思路:这个题,不能全说是搜索,还含有模拟,但是确实少不了搜索这一过程!

这个题采用了回溯的思想,然后就是注意一下3.4号球员是不能在同一排的,而且3号在前排的话只能是在第四号位!其余的应该就没什么了,当然细节也是要注意的嘛!

因为只有一组结果,所以把结果也放出来吧!


代码如下:


#include<cstdio>#include<iostream>#include<cstring>using namespace std;int pos_can_stand[6][6];//表示队员i能否站在位置j,1表示能,0表示不能!bool pos_can_use[6];//表示位置号是否可以使用,true表示没人,可以使用,false表示有人了不可以使用!int num[6];//表示队员的最终站位!void init(){    for(int i=0; i<6; i++)        for(int j=0; j<6; j++)            if(i==j)                pos_can_stand[i][j]=0;            else                pos_can_stand[i][j]=1;//因为每一个队员的球衣号码都与他们的站位号不同!    pos_can_stand[0][4] = 0;//1号队员不在后排    pos_can_stand[0][5] = 0;//1号队员不在后排    pos_can_stand[1][4] = 0;//2号队员不是二传手    pos_can_stand[2][1] = 0;//3号队员不是二传手    pos_can_stand[2][4] = 0;//3号队员不是二传手    pos_can_stand[4][2] = 0;//5号队员不是副攻手    pos_can_stand[4][5] = 0;//5号队员不是副攻手    pos_can_stand[5][2] = 0;//6号队员不是副攻手    pos_can_stand[5][0] = 0;//6号队员不能站后排    pos_can_stand[5][4] = 0;//6号队员不能站后排    for(int i=0; i<6; i++)        num[i]=-1;//初始化!    for(int i=0; i<6; i++)        pos_can_use[i]=true;}void fun(){    int sum_num=0,pos;    while(sum_num<6)    {        for(pos=0; pos<6;)        {            if(sum_num==3)//如果第四号队员            {                if(num[2]==3)//如果3号队员站到了4号位(即唯一的前排可能),则4号队员应站后排                {                    pos_can_stand[3][1]=0;                    pos_can_stand[3][2]=0;                    pos_can_stand[3][3]=0;                }                else//表明第三号队员是站在后排!也就是说第四号球员只能站在前排了!                {                    pos_can_stand[3][0]=0;                    pos_can_stand[3][4]=0;                    pos_can_stand[3][5]=0;                }            }            else//如果回溯的话,需要对第四位队员进行恢复,否则会发生错误,因为它的站位限制不固定            {                for(int i=0; i<6; i++)                    if(i!=3)                        pos_can_stand[3][i]=1;            }            if(pos_can_stand[sum_num][pos]&&pos_can_use[pos])            {                //如果当前的pos位置是可以使用的并且队员是可以在这个位置上的话                num[sum_num]=pos;//把pos这个位置给sum_num+1号队员来站!                pos_can_use[pos]=false;//此位置已经有人了!                sum_num++;                break;//退出for循环!            }            else                pos++;//不然寻找下一个位置!            while(pos==6)//如果找完了所有得位置都没发现能够符合条件,那就回溯!            {                sum_num--;//回溯到上一个队员!                pos=num[sum_num];                pos_can_use[pos]=true;//此时由于需要重新给sum_num找位置,                //所以需要把之前使用的位置标记为没人使用!                num[sum_num]=-1;                pos++;//然后找下一个位置!            }        }    }}void print(){    for(int i=0; i<6; i++)        printf("第[%d]位队员所站的位置是[ %d ]......\n",i+1,num[i]+1);}int main(){    init();    fun();    print();    return 0;}


0 0
原创粉丝点击