首页 > 代码库 > UVa816 - Abbott's Revenge

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