UVa816 - Abbott's Revenge
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa816 - Abbott's Revenge相关的知识,希望对你有一定的参考价值。
题意
走迷宫,给初始位置与其离开初始位置时的朝向和所要到达的位置,给一些结点和进入此结点的朝向与此朝向的可转向,求最短路。
特殊点在于每个位置上都有方向与转向
思路
bfs求迷宫最短路
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <queue> #include <string> const int maxn = 10; using namespace std; const char* dirs = "NESW"; const char* turns = "FLR"; const int dr[] = {-1, 0, 1, 0}; const int dc[] = { 0, 1, 0,-1}; int dir_id(char c) {return strchr(dirs, c) - dirs; } int turn_id(char c) {return strchr(turns, c) - turns; } int r0, c0, r1, c1, r2, c2, dir; int has_edge[maxn][maxn][4][3], d[maxn][maxn][4]; struct Node { int r, c, dir; Node(int r = 0, int c = 0, int dir = 0):r(r),c(c),dir(dir){} }; Node p[maxn][maxn][4]; Node walk(const Node& u, int turn) { int dir = u.dir; if(turn == 1) dir = (dir + 3) % 4; else if(turn == 2) dir = (dir + 1) % 4; return Node(u.r+dr[dir], u.c+dc[dir], dir); } bool judge(int r, int c) { return r > 0 && r < 10 && c > 0 && c < 10; } void print_ans(Node u) { vector<Node> nodes; while(1){ nodes.push_back(u); if(d[u.r][u.c][u.dir] == 0) break; u = p[u.r][u.c][u.dir]; } nodes.push_back(Node(r0,c0,dir)); int len = nodes.size(), cnt = 0; for(int i = len - 1; i >= 0; i--){ if(cnt % 10 == 0) cout << " "; cout << " (" << nodes[i].r << "," << nodes[i].c << ")"; if(++cnt % 10 == 0) cout << endl; } if(len % 10) cout << endl; } void solve() { queue<Node> q; memset(d, -1, sizeof d); Node n(r1, c1, dir); d[n.r][n.c][n.dir] = 0; q.push(n); while(!q.empty()){ Node u = q.front(); q.pop(); if(u.r == r2 && u.c == c2) {print_ans(u); return; } for(int i = 0; i < 3; i++) { Node v = walk(u, i); if(has_edge[u.r][u.c][u.dir][i] && judge(v.r, v.c) && 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); } } } cout << " No Solution Possible" << endl; } int main() { // freopen("in.txt","r",stdin); string str; while(cin >> str && str != "END"){ cout << str << endl; char ch; cin >> r0 >> c0 >> ch >> r2 >> c2; dir = dir_id(ch); r1 = r0 + dr[dir]; c1 = c0 + dc[dir]; memset(has_edge, 0, sizeof has_edge); int r, c; while(cin >> r && r){ cin >> c; string s; while(cin >> s && s != "*"){ int len = s.size(); for(int i = 1; i < len; i++) has_edge[r][c][dir_id(s[0])][turn_id(s[i])] = 1; } } solve(); } return 0; }
以上是关于UVa816 - Abbott's Revenge的主要内容,如果未能解决你的问题,请参考以下文章