bfs找迷宫最短路,不过比传统迷宫问题多了方向,所以加一维就行。
被UVA的输出格式搞崩了心态。。。(默默吐槽一下)
详见代码注释:
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const char* dir = "NESW";
const char* turn = "FLR";
const int dx[] = { -1,0,1,0 }; //注意本题的横坐标纵坐标与一般直角坐标系的区别
const int dy[] = { 0,1,0,-1 };
int bdir, bx, by, ex, ey;
int step[10][10][4]; //每种状态的步数
bool edg[10][10][4][3]; //是否存在该边
struct node {
int x, y, dir;
node(int x = 0, int y = 0, int dir = 0) :x(x), y(y), dir(dir) {}
}last[10][10][4]; //上一步
//方向转换为数字表示
int todir(char c)
{
return strchr(dir, c) - dir;
}
//转向转换为数字表示
int toturn(char c)
{
return strchr(turn, c) - turn;
}
//判断是不是表示方向的字母
bool isdir(char c)
{
return c == 'N' || c == 'E' || c == 'S' || c == 'W';
}
//判断是不是表示转向的字母
bool isturn(char c)
{
return c == 'F' || c == 'L' || c == 'R';
}
//读入
bool input()
{
string ss;
cin >> ss;
if (ss == "END") return 0;
cout << ss << endl;//输出第一行字符串
memset(step, -1, sizeof(step)); //初始化
memset(edg, 0, sizeof(edg));
char ch;
cin >> bx >> by >> ch >> ex >> ey; //读入起点,起始方向,终点
bdir = todir(ch); //起始方向数字表示
int tx, ty;
while (cin >> tx && tx) {
cin >> ty;
string s;
getline(cin, s);
for (int i = 0; i < s.size(); i++) {
if (isdir(s[i])) {
int dir1 = todir(s[i]);
while (isturn(s[++i])) {
int turn1 = toturn(s[i]);
edg[tx][ty][dir1][turn1] = 1; //存在该边
}
}
}
}
edg[bx][by][bdir][0] = 1; //起点及起始方向
return 1;
}
void print_ans(node u)
{
vector<node> ans;
while (1) {
ans.push_back(u);
if (step[u.x][u.y][u.dir] == 0) break; //到起点退出
u = last[u.x][u.y][u.dir]; //上一步
}
int cnt = 0;
for (int i = ans.size() - 1; i >= 0; i--) {
if (cnt % 10 == 0) cout << " ";
cout << " (" << ans[i].x << "," << ans[i].y << ")";
if (++cnt % 10 == 0) cout << endl;
}
if (ans.size() % 10) cout << endl;
}
node walk(node u, int turn)
{
int dir = u.dir;
if (turn == 1) dir = (dir + 3) % 4; //逆时针
if (turn == 2) dir = (dir + 1) % 4; //顺时针
return node(u.x + dx[dir], u.y + dy[dir], dir);
}
void solve()
{
queue<node> q;
q.push(node(bx, by, bdir)); //起点
step[bx][by][bdir] = 0;
while (q.size()) {
node u = q.front();
q.pop();
if (u.x == ex && u.y == ey) {
print_ans(u);
return;
}
for (int i = 0; i < 3; i++) {
node v = walk(u, i);
if (edg[u.x][u.y][u.dir][i] && step[v.x][v.y][v.dir] == -1) {
step[v.x][v.y][v.dir] = step[u.x][u.y][u.dir] + 1;
last[v.x][v.y][v.dir] = u;
q.push(v);
}
}
}
cout << " No Solution Possible\n"; //无解
}
int main(void)
{
//freopen("D:\\out.txt", "w", stdout);
while (input()) {
solve();
}
return 0;
}