这个题的题意如图所示:
一开始理解起来可能有点困难,但是多看两遍就可以了.......仔细看下题目的每一个要求,这个对解题有很大影响!
思路:这个题,不能全说是搜索,还含有模拟,但是确实少不了搜索这一过程!
这个题采用了回溯的思想,然后就是注意一下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; }
时间: 2024-11-14 13:02:26