题意:Z每走一步S就要往相反的方向走一步(所走的那步假如是墙,或者出界,S不动)如果能找到S请输出最小的步数,不能输出“Bad Luck!”
解发:广搜,vis[][][][]标记Z,S已走过的路。
注意:特别要注意,此题的地图必须用gets()或scanf(“%s”)输入,其中的缘由本人也不知,但我已经故意尝试用cin输入地图,但结果是wa。代码后有大量的测试数据,测试结果运行我的代码即可。
ac代码:
View Code
#include<iostream> #include<queue> using namespace std; const int m=22; char map[m][m];//地图 int vis[m][m][m][m];//用作标记 int nn[4][2]={0,1,-1,0,0,-1,1,0};//方向向量:右,上,左,下 struct node { int i,j; //存储Z的坐标 int x,y;//存储S的坐标 int step;//计算步数 }; bool outside(struct node temp,int n,int m) //判断是否出界 { if(temp.i>0&&temp.i<=n&&temp.j>0&&temp.j<=m&&temp.x>0&&temp.x<=n&&temp.y>0&&temp.y<=m) return 1; return 0; } bool meet( struct node temp) //判断是否相邻或同位 { int i; for(i=0;i<4;i++)//相邻 { if(temp.i+nn[i][0]==temp.x&&temp.j+nn[i][1]==temp.y) return 1; } if(temp.i==temp.x&&temp.j==temp.y)//同位 return 1; return 0; } int main() { int n,m; queue<struct node>q; struct node temp; while(cin>>n>>m) { int i,j; memset(vis,0,sizeof(vis)); getchar(); for(i=1;i<=n;i++) { gets(map[i]+1); //此处防止出界 for(j=1;j<=m;j++) { if(map[i][j]=='S') { temp.x=i; temp.y=j; } if(map[i][j]=='Z') { temp.i=i; temp.j=j; temp.step=0; } } } q.push(temp); vis[temp.i][temp.j][temp.x][temp.y]=1; if(meet(q.front())) { cout<<"0"<<endl; q.pop(); continue; } int k,foat=0,x,y; while(!q.empty()) { for(i=0;i<4;i++) { k=i%2==0?i==0?2:0:i==1?3:1; //\此处三个条件语句,确保S的方向与Z的方向相反 temp.i=q.front().i+nn[i][0]; temp.j=q.front().j+nn[i][1]; x=q.front().x+nn[k][0]; y=q.front().y+nn[k][1]; if(map[x][y]=='X'||(x<=0||x>n||y<=0||y>m))//判断S是的下一步是否是墙或出界 { temp.x=q.front().x; temp.y=q.front().y; } else //若下一步是墙或出界,S原地不动 { temp.x=x; temp.y=y; } if(outside(temp,n,m)&&vis[temp.i][temp.j][temp.x][temp.y]!=1&&map[temp.i][temp.j]!='X') { //判断是否出界,走过,或是墙 temp.step=q.front().step+1; vis[temp.i][temp.j][temp.x][temp.y]=1; q.push(temp); } if(meet(q.front())) { foat=1; break; } }//end->for if(foat)break; q.pop(); }//end->while if(foat) cout<<q.front().step<<endl; else cout<<"Bad Luck!"<<endl; while(!q.empty()) q.pop(); } return 0; }