#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<queue> using namespace std; struct Node//每一个结点的属性 { int r,c,dir; Node(int a = 0,int b = 0 ,int c = 0):r(a),c(b),dir(c){} }; int has_eage[100][100][4][3];//记录每个结点以该朝向进来后可以如何转向 Node p[100][100][4]; int d[100][100][4];//用于记录到达该条路线的最短长度,也是防止重复走该路的方法 int r1, c1, dir;//起始位置和朝向 int r2, c2;//终止位置和朝向 const char* dirs = "NESW";//分别代表上右下左 const char* turns = "FLR";//分别代表进入一个结点时该如何走 int dr[] = { -1,0,1,0 }; int dc[] = { 0,1,0,-1 };//根据朝向和转弯方式来移动行列s int T(char s) { if (s == ‘F‘)return 0; else if (s == ‘L‘) return 1; else if (s == ‘R‘) return 2; } int D(char s) { if (s == ‘N‘) return 0; else if (s == ‘E‘) return 1; else if (s == ‘S‘) return 2; else if (s == ‘W‘) return 3; } Node walk(Node u,int turn)//修改结点的位置与方向 { if (turn == 1)u.dir = (u.dir + 3) % 4; if (turn == 2)u.dir = (u.dir + 1) % 4; return Node(u.r + dr[u.dir], u.c + dc[u.dir], u.dir); } void print_ans(Node s)//打印最后结果 { vector<Node> v; while (true) { v.push_back(s); if (d[s.r][s.c][s.dir] == 0) break; s = p[s.r][s.c][s.dir]; } v.push_back(Node(r1, c1, dir)); int cnt = 0; for (int i = v.size() - 1; i >= 0; i--) { if (cnt % 10 == 0) printf(" "); printf(" (%d,%d)", v[i].r, v[i].c); if ((++cnt)% 10 ==0) puts(""); } if (v.size() % 10 != 0)printf("\n"); } void bfs() { queue<Node> q; Node u(r1, c1, dir); q.push(u); memset(d, -1, sizeof(d)); int h = 0; while (!q.empty()) { Node u = q.front(); q.pop(); if(h) if (u.r == r2 && u.c == c2) { print_ans(u); return; } if(h++) for (int i = 0; i < 3; i++) { Node v = walk(u,i); if (has_eage[u.r][u.c][u.dir][i]&&d[v.r][v.c][v.dir]<0) { d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1; p[v.r][v.c][v.dir] = u; q.push(v); } } else { Node v = walk(u, 0); d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1; p[v.r][v.c][v.dir] = u; q.push(v); } } printf(" "); printf(" No Solution Possible\n"); } int main(void) { //int has_eage[100][100][4][3];//记录每个结点以该朝向进来后可以如何转向 //Node p[100][100][4]; //int d[100][100][4]; string m; while (cin >> m && m != "END") { memset(has_eage, 0, sizeof(has_eage)); memset(p, 0, sizeof(p)); cout << m << endl; int a = 1, b = 1; char s; cin >> r1 >> c1 >> s >> r2 >> c2; dir = D(s); has_eage[r1][c1][dir][0] = 1; while (cin >> a && a) { cin >> b; string s; //将has_eage中结点的转向记录 while (cin >> s && s != "*") { for (int i = 0; i < 4; i++) { if (*(dirs + i) == s[0]) { for (int j = 1; j < s.size(); j++) { int t = T(s[j]); has_eage[a][b][i][t] = 1; } break; } } } } bfs(); } return 0; }
原文:https://www.cnblogs.com/loliconsk/p/14382516.html