题意:走迷宫,在某个点,对于某个当前前进方向,只能往左、右、前三个方向中的某些方向走。
思路:BFS。因为即使在同一个点,当前前进方向不同,能走的方向也不同,所以把一个点拆成四个来BFS,把每个点的前驱存起来,然后递归输出解即可。点的位置方向信息可以映射到一个整数,这样做比较方便。
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <iomanip> #include <cstdlib> #include <string> #include <memory.h> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <ctype.h> #define INF 1000000010 #define ll long long #define max3(a,b,c) max(a,max(b,c)) #define MAXN 1000 using namespace std; string name; int vis[4010]; int path[4010]; int cnt; inline int char2int(char ch) { if(ch=='E'||ch=='F')return 0; if(ch=='S'||ch=='L')return 1; if(ch=='W'||ch=='R')return 2; if(ch=='N')return 3; return -1; } inline int hash(int r,int c,int dir){ return r*40+c*4+dir; } inline void dehash(int n,int& r,int& c,int& dir){ dir=n%4; n/=4; c=n%10; n/=10; r=n; } vector<int> data[10][10][5]; void print(int n){ if(n==-1)return; print(path[n]); int a,b,c; dehash(n,a,b,c); if(!(cnt%10))printf("\n "); printf(" (%d,%d)",a,b); cnt++; } int main(){ int startR,startC; int goalR,goalC; while(cin>>name){ if(name=="END")break; memset(vis,0,sizeof(vis)); memset(path,-1,sizeof(path)); memset(data,0,sizeof(data)); cnt=0; char ch; cin>>startR>>startC>>ch>>goalR>>goalC; data[startR][startC][char2int(ch)].push_back(0); int r,c; while(cin>>r){ if(r==0)break; cin>>c; string str; while(cin>>str){ if(str=="*")break; int dir=char2int(str[0]); for(int i=1;i<str.size();i++){ data[r][c][dir].push_back( char2int(str[i]) ); } } } bool ok=false; int end; int start=hash(startR,startC,char2int(ch)); queue<int> que; que.push( start ); vis[start]=1; int test=0; while(!que.empty()){ int cur=que.front(); que.pop(); int curR,curC,curD; dehash(cur,curR,curC,curD); if(curR==goalR&&curC==goalC&&test){ ok=true; end=cur; break; } test++; for(int i=0;i<data[curR][curC][curD].size();i++){ int tmpD; if(data[curR][curC][curD][i]==0){ tmpD=curD; } if(data[curR][curC][curD][i]==1){ tmpD=(curD+3)%4; } if(data[curR][curC][curD][i]==2){ tmpD=(curD+1)%4; } int nn; if(tmpD==0){ nn=hash(curR,curC+1,tmpD); }else if(tmpD==1){ nn=hash(curR+1,curC,tmpD); }else if(tmpD==2){ nn=hash(curR,curC-1,tmpD); }else if(tmpD==3){ nn=hash(curR-1,curC,tmpD); } if(!vis[nn]){ vis[nn]=true; que.push(nn); path[nn]=cur; } } } cout<<name; if(ok){ print(end); printf("\n"); }else{ printf("\n No Solution Possible\n"); } } return 0; }