题目大意
贝西误把自己困在了FJ谷仓的一侧。因为她的视力很差,她在脱困时需要你的帮助。
谷仓的平面图是一个方格图,有些方格(即单位)是空的,其他的则是不可通过的柴草堆。贝西从左下角开始(方格1,1)想一路搬到右上角。你可以引导她,告诉她一个指令序列,指令可以为“前进”“左转90度”“右转90度”。你需要得出能够使她到达目的地所用的最短指令序列。如果你指示贝西离开谷仓或至柴草堆,她不会移动,会直接跳到下一个命令序列。
不幸的是,贝西不知道她一开始所朝的方向(可能是上或右),而序列无需考虑这种情况,(使得bessie无论是朝上还是朝右,根据给出的指令都能到达终点。)
注意:到了终点就不会再移动了
(2≤N≤20)
题目分析
因为N很小,而对于此题,我们什么都不知道,所以考虑搜索。
因为一开始不知道是向上还是向右,所以我们的vis数组要开六维,分别记录一开始向上或向右的情况。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=25; 4 5 int dx[5]={-1,0,1,0}; 6 int dy[5]={0,1,0,-1}; 7 8 int n; 9 bool blk[MAXN][MAXN],vis[MAXN][MAXN][4][MAXN][MAXN][4]; 10 int dis[MAXN][MAXN][4][MAXN][MAXN][4]; 11 struct Node{ 12 int x,y,d; 13 inline bool Ok(){return x>=1&&x<=n&&y>=1&&y<=n&&!blk[x][y];} 14 }; 15 struct q_Node{ 16 Node p1,p2; 17 void mrk(){vis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d]=true;} 18 bool IsMrked(){return vis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d];} 19 int &get(){return dis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d];} 20 }q1,p,nxt; 21 queue<q_Node> q; 22 inline void Move(Node &d,Node f,int w){ 23 d=f; 24 if(w==0){ 25 if(d.x==1&&d.y==n) return; 26 d.x+=dx[d.d]; 27 d.y+=dy[d.d]; 28 if(!d.Ok()) d=f; 29 } 30 else if(w==1){ 31 ++d.d; 32 if(d.d==4) d.d=0; 33 } 34 else if(w==2){ 35 --d.d; 36 if(d.d==-1) d.d=3; 37 } 38 } 39 int main(){ 40 memset(dis,0x3f,sizeof(dis)); 41 scanf("%d",&n); 42 for(int i=1;i<=n;++i){ 43 getchar(); 44 for(int j=1;j<=n;++j) 45 blk[i][j]=(getchar()=='H'); 46 } 47 q1.p1.x=q1.p2.x=n; 48 q1.p1.y=q1.p2.y=q1.p2.d=1; 49 q1.get()=0; 50 q.push(q1); 51 while(!q.empty()){ 52 p=q.front(); 53 q.pop(); 54 int w=p.get(); 55 for(int i=0;i<3;++i){ 56 Move(nxt.p1,p.p1,i); 57 Move(nxt.p2,p.p2,i); 58 int &nd=nxt.get(); 59 if(nd>w+1){ 60 nd=w+1; 61 if(!nxt.IsMrked()){ 62 q.push(nxt); 63 nxt.mrk(); 64 } 65 } 66 } 67 } 68 int ans=0x3f3f3f3f; 69 for(int i=0;i<4;++i) 70 for(int j=0;j<4;++j) 71 ans=min(ans,dis[1][n][i][1][n][j]); 72 printf("%d ",ans); 73 return 0; 74 }