【题目】排球队员站位问题
图为排球场的平面图,其中一、二、三、四、五、六为位置编号,二、三、四号位置为前排,
一、六、五号位为后排。某队比赛时,一、四号位放主攻手,二、五号位放二传手,三、六号位
放副攻手。队员所穿球衣分别为1,2,3,4,5,6号,但每个队员的球衣都与他们的站位
号不同。已知1号、6号队员不在后排,2号、3号队员不是二传手,3号、4号队员不在同一
排,5号、6号队员不是副攻手。
编程求每个队员的站位情况。
思路: 1、先得到每个队员能站在哪些位置,然后与不能站的位置区分,player[].can[j]来区分,1表示可以站,0表示不能站。
2、找到最后的解采用回溯法,在这里还要处理第三号和第四号不能在同一排的问题(这里我的程序里实现是很丑陋的,效率较低,因为每次循环都要处理这段)
正确解: 正确的站位顺序为: 1 2 3 4 5 6
三 六 四 五 一 二
源代码:#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
struct player{
int position;
BOOL can[6];
}Player[6];
/* 初始化队员属性 */
void init_player(struct player Player[])
{
int i=0,j=0;
while(i<6){
j=0;
while(j<6){
if(j==i){
Player[i].can[j]=0;
}
else{
Player[i].can[j]=1;
}
j++;
}
Player[i].position=i;
i++;
}//initial
Player[0].can[4]=0;//1号不在后排
Player[0].can[5]=0;//1号不在后排
Player[1].can[4]=0;//2号不是二传手
Player[2].can[1]=0;//3号不是二传手
Player[2].can[4]=0;//同上
Player[4].can[2]=0;//5号不是副攻手
Player[4].can[5]=0;//同上
Player[5].can[0]=0;//6号不在后排
Player[5].can[4]=0;//同上
Player[5].can[2]=0;//6号不是副攻手
}
/* 选出适合的站位 */
int select(struct player p[])
{
BOOL judge[6];
int i,j;
for(i=0;i<6;i++)
judge[i]=0;
i=0;
while(i<6){
j=0;
while(j<6){
if(i==3){//第四个队员时,不能与第三个队员在一排
if(p[2].position!=3){//第三个队员在第四个位置,前排
p[3].can[0]=0;//则第四个队员不能在前排
p[3].can[4]=0;
p[3].can[5]=0;
}
else{//第三个队员不在第四个位置,则在后排
p[3].can[1]=0;//则第四个队员不能在后排
p[3].can[2]=0;
}
}
else{
p[3].can[0]=1;//恢复第四个队员的初始状态
p[3].can[4]=1;
p[3].can[5]=1;
p[3].can[1]=1;
p[3].can[2]=1;
}
if(p[i].can[j]!=0 && judge[j]==0){ //可以站此位置
p[i].position=j;//注明i队员所站位置
judge[j]=1;//表明已被占
i++;//下一球员
break;
}
else{ //向后找
j++;
}
while(j==6){ //已经找完,但无合适的位置,回溯
i--;
j=p[i].position+1; //上一级的j加1,有可能等于6
judge[j-1]=0;
}
}//inside while
}//outside while
return 0;
}
int main(int argc,char **argv)
{
int i;
init_player(Player);
select(Player);
printf("Player number:1 2 3 4 5 6 \n");
printf("Player position:");
for(i=0;i<6;i++){
printf("%d ",Player[i].position+1);
}
printf("\n");
return 0;
}
|
阅读(1900) | 评论(0) | 转发(0) |