Uva 816 Abbott's Revenge 紫书165页例题

本文深入探讨了使用C++实现的一种迷宫寻路算法,通过定义方向、状态转移和路径回溯等关键概念,详细介绍了如何利用队列和地图数据结构来寻找从起点到终点的最短路径。文章提供了完整的代码示例,包括状态转移矩阵、路径记录和读取案例等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;

const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int dir[4][2]={-1,0,0,1,0,-1,1,0};//上N右E左W下S
int to[4][3]={//FLR
    {0,2,1},
    {1,0,3},
    {2,3,0},
    {3,1,2}
};
int n, m;
int sx, sy, ex, ey;
char SIN;
map<char, int> mp;
int buf[10][10][4][3];
int vis[10][10][4];
int fa[1000];
struct lp {
    int x, y, step, f;
};
bool readcase() {
    string s; cin>>s;
    if(s == "END") return 0;
    cout<<s<<"\n";
    memset(buf, 0, sizeof(buf)); memset(vis, 0x3f, sizeof(vis));
    cin>>sx>>sy;
    cin>>SIN;
    cin>>ex>>ey;
    cin>>n;
    while(n != 0) {
        cin>>m;cin>>s;
        while(s != "*") {
            int len = s.length();
            for(int i = 1; i < len; ++i) {
                buf[n][m][mp[s[0]]][mp[s[i]]] = 1;
            }
            cin>>s;
        }
        cin>>n;
    }
    return 1;
}
void solve() {
    int ax = sx + dir[mp[SIN]][0], ay = sy + dir[mp[SIN]][1];
    queue<lp> Q;
    fa[ax*10+ay+mp[SIN]*100]=sx*10+sy;
    Q.push(lp{ax,ay,1,mp[SIN]});
    int ans = INF, last = -1;
    while(!Q.empty()) {
        lp A = Q.front(); Q.pop();
        if(A.x == ex && A.y == ey) {
            if(A.step < ans) {
                ans = A.step;
                last = A.x*10+A.y+A.f*100;
            }
        }
        for(int i = 0; i < 3; ++i) {
            if(buf[A.x][A.y][A.f][i] == 0) continue;
            int px = dir[to[A.f][i]][0]+A.x;
            int py = dir[to[A.f][i]][1]+A.y;
            int pf = to[A.f][i];
            int pt = A.step + 1;
            if(px < 1 || px > 9 || py < 1 || py > 9) continue;
            if(vis[px][py][pf] > pt) {
                vis[px][py][pf] = pt;
                fa[px*10+py+pf*100]=A.x*10+A.y+A.f*100;
                Q.push(lp{px,py,pt,pf});
            }
        }
    }
    if(ans == INF) printf("  No Solution Possible\n");
    else {
        std::vector<pair<int,int> > vs;
        while((last%100)/10!=ax||last%10!=ay||last/100!=mp[SIN]) {
            vs.push_back({(last%100)/10,last%10});
            last = fa[last];
        }
        vs.push_back({ax,ay});
        vs.push_back({sx,sy});
        int len = vs.size();
        printf("  ");
        for(int i = len - 1, j = 1; i >= 0; --i, ++j) {
            printf("(%d,%d)", vs[i].first, vs[i].second);
            if(i == 0 || j % 10 == 0) {
                printf("\n");
                if(i != 0) printf("  ");
            }else printf(" ");
        }
    }
}
int main() {
    mp['N']=0;mp['E']=1;mp['W']=2;mp['S']=3;
    mp['F']=0;mp['L']=1;mp['R']=2;
    while(readcase()) solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值