给出迷宫的结点,和迷宫结点处朝向与行走方向的限制关系,求从入口走到出口的最短路径。
最短路问题BFS,用三位数组d[maxn][maxn][4]记录是否经过,结构体数组p[maxn][maxn][4]记录上一步的位置,达到出口就打印解。
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<queue> using namespace std; const int maxn=12; const char* dirs="NESW"; const char* turns="FLR"; const int dr[]={-1,0,1,0}; const int dc[]={0,1,0,-1}; int r0,c0,r1,c1,r2,c2,rx,cx,dir,dirx,turnx,d[maxn][maxn][4]; bool has_edge[maxn][maxn][4][4]; string s,s0; struct Node{ int r,c,dir; Node(int r=0,int c=0,int dir=0):r(r),c(c),dir(dir){} }; Node p[maxn][maxn][4]; int dir_id(char c){ return (int)(strchr(dirs,c)-dirs); } int trun_id(char c){ return (int)(strchr(turns,c)-turns); } Node walk(const Node& u,int turn){ int dir=u.dir; if(turn==1) dir=(dir+3)%4; if(turn==2) dir=(dir+1)%4; return Node(u.r+dr[dir],u.c+dc[dir],dir); } bool inside(int x,int y){ return (x>0&&x<10&&y>0&&y<10); } void print_ans(Node u){ vector<Node>nodes; while(1){ nodes.push_back(u); if(!d[u.r][u.c][u.dir]) break; u=p[u.r][u.c][u.dir]; } nodes.push_back(Node(r0,c0,dir)); int cnt=0; for(int i=(int)nodes.size()-1;i>=0;i--){ if(cnt%10==0) printf(" "); printf(" (%d,%d)",nodes[i].r,nodes[i].c); if(++cnt%10==0) printf("\n"); } if(nodes.size()%10) printf("\n"); } void solve(){ queue<Node>q; memset(d,-1,sizeof(d)); Node u(r1,c1,dir); d[u.r][u.c][u.dir]=0; q.push(u); while(!q.empty()){ Node u=q.front(); q.pop(); if(u.r==r2&&u.c==c2){ print_ans(u); return; } for(int i=0;i<3;i++){ Node v=walk(u,i); if(has_edge[u.r][u.c][u.dir][i]&&inside(v.r,v.c)&&d[v.r][v.c][v.dir]<0){ d[v.r][v.c][v.dir]=d[u.r][u.c][u.dir]+1; p[v.r][v.c][v.dir]=u; q.push(v); } } } printf(" No Solution Possible\n"); return; } bool read(){ cin>>s0; if(s0=="END") return false; cout<<s0<<endl; memset(has_edge,0,sizeof(has_edge)); memset(p,0,sizeof(p)); cin>>r0>>c0>>s>>r2>>c2; for(int i=0;i<4;i++) if(s[0]==dirs[i]){ dir=i; break; } r1=r0+dr[dir]; c1=c0+dc[dir]; while(cin>>rx&&rx){ cin>>cx; while(cin>>s){ if(s=="*") break; for(int i=0;i<4;i++) if(s[0]==dirs[i]){ dirx=i; break; } for(int i=1;i<s.size();i++){ for(int j=0;j<3;j++) if(s[i]==turns[j]){ turnx=j; break; } has_edge[rx][cx][dirx][turnx]=true; } } } return true; } int main(){ while(read()){ solve(); } return 0; }