UVa 816 Abbott's Revenge(状态压缩BFS)

来源:互联网 发布:淘宝手机找回是真的吗 编辑:程序博客网 时间:2024/06/03 12:52

复杂的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;}


0 0
原创粉丝点击