题意简述:
从不同方向(北N, 东E, 南S, 西W)进入迷宫的任意位置,只能走向指定的几个方向(前进F, 左转L, 右转R)。给定起点及方向、终点,要求输出最短路径。输入输出格式见原题。
题解:用BFS求最短路径,三维数组(row, col, dir)记录节点信息,四维数组(row, col, dir, turn)记录移动信息。注意初始化等细节。//代码输出行的缩进格式未控制
//Abbott's Revenge
//Yhq
#include<iostream>
#include<string>
#include<sstream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
struct Node;
const char DIR[]={'N', 'E', 'S', 'W'};
const char TURN[]={'F', 'L', 'R'};
int c_to_dir(char ch) {
switch (ch) {
case 'N': return 0;
case 'E': return 1;
case 'S': return 2;
case 'W': return 3;
}
}
int c_to_turn(char ch) {
switch (ch) {
case 'F': return 0;
case 'L': return 1;
case 'R': return 2;
}
}
bool possib[10][10][4][3]={0}; //possibility[row][col][dir][turn]
bool hasR[10][10][4]={0}; //has reached [row][col][dir]
struct Node{
int row, col, dir;
Node() {}
Node(int r, int c, int d): row(r), col(c), dir(d) {}
bool operator == (const Node& u) {
return row==u.row && col==u.col && dir==u.dir;
}
};
Node start, end;
Node lastNode[10][10][4];
//walking from u to a new node
const int row_dir[]={-1, 0, 1, 0};
const int col_dir[]={0, 1, 0, -1};
Node walk (const Node& u, int turn) {
int resdir = u.dir;
if (turn==1) resdir+=3; //attention to mod!
else if (turn==2) resdir++;
resdir = resdir%4;
return Node(u.row+row_dir[resdir], u.col+col_dir[resdir], resdir);
}
void input() {
char startdir;
cin>>start.row>>start.col>>startdir>>end.row>>end.col;
start.dir = c_to_dir(startdir);
string str;
while (getline(cin,str)) {
if (str[0]=='0') return;
int r, c;
stringstream ss(str);
ss>>r;
ss>>c;
string s;
while (ss>>s) {
if (s=="*") break;
int d=c_to_dir(s[0]);
for (int i=1; i<s.length(); ++i) possib[r][c][d][c_to_turn(s[i])]=true;
}
}
}
void print(Node);
void solve () {
queue<Node> que;
Node u = walk(start,0);
lastNode[u.row][u.col][u.dir]=start;
que.push(u);
hasR[u.row][u.col][u.dir]=true;
while (!que.empty()) {
Node u0=que.front();
que.pop();
//if (que.empty()) cout<<"empty now"<<endl;
if (u0.row==end.row && u0.col==end.col) {
print(u0);
return;
}
for (int i=0; i<3; ++i) {
if (possib[u0.row][u0.col][u0.dir][i]) {
//cout<<"possible: "<<i<<endl;
Node newnode=walk(u0,i);
if (!hasR[newnode.row][newnode.col][newnode.dir]) {
hasR[newnode.row][newnode.col][newnode.dir]=true;
lastNode[newnode.row][newnode.col][newnode.dir]=u0;
que.push(newnode);
//print(newnode);
}
}
}
}
cout<<"No Solution Possible"<<endl;
}
void print (Node u) {
vector<Node> vec;
Node temp = u;
while (1) {
vec.push_back(temp);
if (temp==start) break;
temp=lastNode[temp.row][temp.col][temp.dir];
}
for (int i=vec.size()-1; i>=0; --i) {
cout<<"("<<vec[i].row<<","<<vec[i].col<<")";
if (i!=0) cout<<" ";
else cout<<endl;
}
}
void reset() {
memset(possib,false,sizeof(possib));
memset(hasR,false,sizeof(hasR));
}
int main () {
string name;
while (cin>>name) {
if (name=="END") return 0;
reset();
input();
cout<<name<<endl;
solve();
}
return 0;
}