题意:走迷宫,在某个点,对于某个当前前进方向,只能往左、右、前三个方向中的某些方向走。
思路: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;
}