# UVa 816 - Abbott's Revenge
---
# 題目大意
有一個最多9*9個的迷宮。輸入起點、離開起點時的朝向和終點,每個點有限制能走的方向,輸出最短路。
要注意初始狀態是 **剛剛離開入口** ,所以即使出口和入口重合,最短路也不爲空。
---
# 題解
有夠麻煩又一堆問題的BFS。因為有朝向哪邊的問題,所以需要多記錄現在的朝向,整體來說就是多一維的BFS。然後設計一下dir陣列對應左、右、前的關係。一邊走一邊紀錄父節點,最後倒著推回去輸出路徑
---
```=c++
#include <iostream>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <algorithm>
#define ll long long
#define pb push_back
#define pf push_front
#define ft first
#define sec second
#define pr pair<int,int>
#define ISCC ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int sx ,sy ,ex ,ey;
int dir[][2] = {{0,1},{1,0},{0,-1},{-1,0}} ,cas ,edge[15][15] ,vis[15][15][4] ,x1 ,y1 ,d[15][15][4];
string name ,s;
char way[] = {'E','S','W','N','L','R','F'};
vector<int> g[15][15][4]; /*每個點可以往哪走 */
struct node{
int gx ,gy;
int from;
node():gx(),gy(),from(){}
node(int a ,int b ,int c):gx(a),gy(b),from(c){}
}fa[10][10][4]; /*紀錄BFS樹的父節點 */
map<char ,int> mp;
char st;
void print(node v)
{
vector<node> ans;
while(1) /*從終點跑回去 */
{
ans.pb(v);
if(d[v.gx][v.gy][v.from]==0) break;
v = fa[v.gx][v.gy][v.from];
}ans.pb(node(sx,sy,mp[st]));
for(int i=ans.size()-1 ,cnt=1 ;i>=0 ;i-- ,cnt++) /*要倒著輸出 */
{
printf(" (%d,%d)",ans[i].gx ,ans[i].gy);
if(cnt == 10 && i!=0) cout << "\n " ,cnt=0;
}cout << '\n';
}
void bfs(node pos)
{
queue<node> que;
x1 = pos.gx+dir[pos.from][0]; y1 = pos.gy+dir[pos.from][1];
que.push(node(x1,y1,pos.from)); d[x1][y1][pos.from] = 0;
int cnt = 0;
while(!que.empty())
{
node now = que.front(); que.pop();
if(now.gx == ex && now.gy == ey) {print(now); return;}/*輸出路徑 */
if(vis[now.gx][now.gy][now.from]) continue;
vis[now.gx][now.gy][now.from] = 1;
int k = now.from; //原朝向
for(auto v : g[now.gx][now.gy][k])
{
int u = (k+v+4)%4; //新朝向
int x = now.gx + dir[u][0] ,y = now.gy + dir[u][1]; /*新座標 */
if(x<1 || y<1 || x>9 || y>9 || !edge[x][y] || vis[x][y][u] || d[x][y][u]>=0) continue;
que.push(node(x,y,u)); d[x][y][u] = d[now.gx][now.gy][now.from]+1;
if(!fa[x][y][u].gx && !fa[x][y][u].gy ) fa[x][y][u] = now; /*紀錄第一次的,不然可能被蓋掉 */
}
}
cout << " No Solution Possible\n";
}
int main()
{
mp['E']=0; mp['S']=1; mp['W']=2; mp['N']=3;
mp['L']=-1; mp['R']=1; mp['F'] = 0;
while(getline(cin,name))
{
memset(fa,0,sizeof(fa)); memset(d,-1,sizeof(d));
for(int i=0 ;i<10 ;i++)
for(int j=0 ;j<10 ;j++) for(int k=0 ;k<4 ;k++) g[i][j][k].clear();
memset(edge,0,sizeof(edge)); memset(vis,0,sizeof(vis));
if(name == "END") break;
cin >> sx >> sy;
cin >> st;
cin >> ex >> ey; /*起、終點*/
edge[sx][sy] = edge[ex][ey] = 1;
int x ,y;
while(cin >> x && x)
{
cin >> y; edge[x][y] = 1;
while(cin >> s)
{
if(s == "*") break;
for(int i=1 ;i<s.size() ;i++) g[x][y][mp[s[0]]].pb(mp[s[i]]) ;
}
}
printf("%s\n ",name.c_str());
bfs(node(sx ,sy ,mp[st]));
getchar();
}
return 0;
}
```