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的主要内容,如果未能解决你的问题,请参考以下文章

UVa816 - Abbott's Revenge

uva 816 Abbott的复仇

UVa 816 Abbott的复仇(BFS)

Uva 816 Abbott的复仇(三元组BFS + 路径还原)

UVa 816 (BFS求最短路)

BFS,优先队列优化