用BFS求最短路。结点有多个状态。
迷宫图,从不同的方向进入一个结点,下一步可以走的方向不同,所以给图增加一个维度表示进入方向,相当于扩充了结点数量,相应地记录前驱的数组也有三个维度。BFS扩充后的图,根据前驱数组打印路径。
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
#define REP(i,n) for(int i=0; i<(n); i++)
using namespace std;
const int dr[] = {-1,0,1,0};
const int dc[] = {0,1,0,-1};
const char dir[] = "NESW";
const char turn[] = "LFR";
const int maxn = 15;
struct Node {
int r, c, dir;
Node(int r=-1, int c=-1, int dir=-1): r(r), c(c), dir(dir) {}
bool bad() { return dir < 0; }
} p[maxn][maxn][4];
int r0, c0, r1, c1, dir1, r2, c2;
bool e[maxn][maxn][4][3];
int dirId(char c) { return strchr(dir,c) - dir; }
int turnId(char c) { return strchr(turn,c) - turn; }
void readCase(){
char c;
cin >> r0 >> c0 >> c >> r2 >> c2;
dir1 = dirId(c);
r1 = r0 + dr[dir1];
c1 = c0 + dc[dir1];
int row, col;
char s[10];
while(cin >> row && row) {
cin >> col;
while(cin >> s && s[0] != '*') {
int k = dirId(s[0]);
for(int i=1; s[i]; i++)
e[row][col][k][turnId(s[i])] = true;
}
}
}
void printAns(Node t) {
vector<Node> ans;
while(1) {
ans.push_back(t);
if(p[t.r][t.c][t.dir].bad()) break;
t = p[t.r][t.c][t.dir];
}
ans.push_back(Node(r0,c0,-1));
int cnt = 0;
for(int i=ans.size()-1; i>=0; i--) {
if(cnt++ % 10 == 0) cout << "\n ";
cout << " (" << ans[i].r << ',' << ans[i].c << ')';
}
cout << endl;
}
void solve() {
queue<Node> q;
q.push(Node(r1,c1,dir1));
while(!q.empty()) {
Node t = q.front(); q.pop();
if(t.r == r2 && t.c == c2) { printAns(t); return; }
REP(i,3) {
int d = t.dir;
if(i==0) d = (d+3)%4;
if(i==2) d = (d+1)%4;
int r = t.r + dr[d];
int c = t.c + dc[d];
if(e[t.r][t.c][t.dir][i] && p[r][c][d].bad()) {
p[r][c][d] = t;
q.push(Node(r,c,d));
}
}
}
cout << "\n No Solution Possible\n";
}
int main() {
char s[25];
while(cin >> s && strcmp(s,"END")) {
cout << s;
memset(p,-1,sizeof(p));
memset(e,0,sizeof(e));
readCase();
solve();
}
return 0;
}