0
点赞
收藏
分享

微信扫一扫

UVA816 Abbott的复仇 Abbott‘s Revenge

微笑沉默 2022-01-24 阅读 50

主要是有三个点,状态是三元的,包括进入某点时的朝向,然后就是对方向的操作,这里包括怎么处理输入的数据,最后就是要打印任意一条路径,所以要在搜索的中间记录路径,然后写一个打印函数,这个代码明天再修改一下

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;

struct state {
    int x, y, dir;
    state(int a, int b, int c): x(a), y(b), dir(c) {}
};

int xs, ys, xe, ye;
char dir;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int vis[10][10][5];
char str[5] = "NESW";
map<pa, vector<string> > mp;
map<char, int> mp2;
int pre[10][10][5];

int getdir(int a, int b) {
    if (b == 'L') {
        if (a) a--;
        else a = 3;
    } else {
        if (a == 3) a = 0;
        else a++;
    }
    return a;
}

int bfs() {
    queue<state> q;
    int r = xs + dx[mp2[dir]];
    int c = ys + dy[mp2[dir]];
    memset(vis, 0, sizeof(vis));
    if (r >= 1 && r <= 9 && c >= 1 && c <= 9) {
        q.push(state(r, c, mp2[dir]));
        vis[r][c][mp2[dir]] = 1;
        pre[r][c][mp2[dir]] = xs * 10 + ys;
    }
    while (!q.empty()) {
        state now = q.front();
        q.pop();
        if (now.x == xe && now.y == ye) { dir = str[now.dir]; return vis[now.x][now.y][now.dir]; }
        pa p = mk(now.x, now.y);
        for (int i = 0; i < sz(mp[p]); i++) {
            if (mp[p][i][0] == str[now.dir]) {
                string t = mp[p][i];
                for (int j = 1; j < sz(t); j++) {
                    int dir_t;
                    if (t[j] == 'F') dir_t = now.dir;
                    else dir_t = getdir(now.dir, t[j]);
                    int x = now.x + dx[dir_t];
                    int y = now.y + dy[dir_t];
                    if (x < 1 || x > 9 || y < 1 || y > 9) continue;
                    if (vis[x][y][dir_t]) continue;
                    q.push(state(x, y, dir_t));
                    vis[x][y][dir_t] = vis[now.x][now.y][now.dir] + 1;
                    pre[x][y][dir_t] = now.x * 100 + now.y * 10 + now.dir;
                }
            }
        }
    }
    return -1;
}

void print() {
    int r = xe, c = ye;
    vector<pa> ans;
    int z = mp2[dir];
    while (true) {
        ans.pb(mk(r, c));
        if (vis[r][c][z] == 1) break;
        int num = pre[r][c][z];
        r = num / 100;
        c = num % 100 / 10;
        z = num % 10;
    }
    ans.pb(mk(xs, ys));
    reverse(all(ans));
    for (int i = 0; i < sz(ans); i++) {
        if (i % 10 == 0) cout << " ";
        cout << " (" << ans[i].fi << "," << ans[i].se << ")";
        if (i % 10 == 9 || i == sz(ans) - 1) cout << endl;
    }
}

int main() {
    mp2['N'] = 0; mp2['E'] = 1; mp2['S'] = 2; mp2['W'] = 3;
    string maze;
    while (cin >> maze && maze != "END") {
        cout << maze << endl;
        cin >> xs >> ys >> dir >> xe >> ye;
        int x, y;
        while (cin >> x && x) {
            cin >> y;
            string ss;
            while (cin >> ss && ss != "*") {
                mp[mk(x, y)].pb(ss);
            }
        }
        int rec = bfs();
        if (rec == -1) cout << "  No Solution Possible\n";
        else print();
        mp.clear();
    }
    return 0;
}
举报

相关推荐

0 条评论