复杂的BFS:求最短路,但是每个点能转的方向是有限制的。
把一个点的状态扩展为4个状态分别表示在该点时面向哪一面.
#pragma warning(disable:4996) #include <iostream> #include <cstdio> #include <string> #include <queue> #include <cstring> #include <vector> using namespace std; struct node{ //定义状态:该题目不是每一个点是一个状态, //而是扩展到了每一个点面朝的方向都是一个状态 node(){} node(int a, int b, int c) :r(a), c(b), dir(c){} int r, c, dir; }; int d[10][10][4];//表示d[r][c][dir]到达状态(r,c,dir)的最短距离,顺便当做vis数组标记访问情况 node p[10][10][4];//表示状态(r,c,dir)的前驱 bool has_edge[10][10][4][3]; node now; int R, C;//终点 int DIR[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1 };//方向数组 bool inside[10][10]; node turn(node t, int type){ int d = t.dir; if (type == 1){ d--; if (d == -1)d = 3; } else if (type == 2){ d++; if (d == 4)d = 0; } return node(t.r + DIR[d][0], t.c + DIR[d][1], d); } bool bfs(){ queue<node>q; memset(d, -1, sizeof d); d[now.r][now.c][now.dir] = 0; q.push(now); while (!q.empty()){ now = q.front(); q.pop(); if (now.r == R&&now.c == C)return true;//此时沿着p数组从now开始找路径 //now出来的可能的三个方向 for (int i = 0; i<3; i++){ node nxt = turn(now, i); if (inside[nxt.r][nxt.c] && has_edge[now.r][now.c][now.dir][i] && d[nxt.r][nxt.c][nxt.dir] == -1){ d[nxt.r][nxt.c][nxt.dir] = d[now.r][now.c][now.dir] + 1; p[nxt.r][nxt.c][nxt.dir] = now; q.push(nxt); } } } return false; } inline int get(char ch){ if (ch == 'N' || ch == 'F')return 0; else if (ch == 'E' || ch == 'L')return 1; else if (ch == 'S' || ch == 'R')return 2; else if (ch == 'W')return 3; return -1; } int main(){ //freopen("in.txt", "r", stdin); string name; char ch; node start; while (cin >> name){ if (name == "END")break; memset(inside, false, sizeof inside); memset(p, 0, sizeof p); memset(has_edge, false, sizeof has_edge); cin >> start.r >> start.c >> ch >> R >> C; inside[start.r][start.c] = inside[R][C] = true; start.dir = get(ch); now.dir = start.dir; now.r = start.r + DIR[now.dir][0]; now.c = start.c + DIR[now.dir][1]; int x, y; while (cin >> x){ if (x == 0)break; cin >> y; inside[x][y] = true; string s; while (cin >> s){ if (s[0] == '*')break; int d = get(s[0]); for (int i = 1; i < (int)s.size(); i++){ has_edge[x][y][d][get(s[i])] = true; } } } cout << name << endl; if (inside[now.r][now.c] && bfs()){ vector<node>ans; while (true){ ans.push_back(now); if (d[now.r][now.c][now.dir] == 0){ ans.push_back(start); break; } now = p[now.r][now.c][now.dir]; } int cnt = 0; for (int i = (int)ans.size() - 1; i >= 0; i--){ if (cnt % 10 == 0)printf(" "); printf(" (%d,%d)", ans[i].r, ans[i].c); if (++cnt % 10 == 0)puts(""); } if ((int)ans.size() % 10 != 0)puts(""); } else{ printf(" No Solution Possible\n"); } } return 0; }