UVa 816 - Abbott's Revenge(BFS+记录状态判重)

来源:互联网 发布:原始对偶知乎 编辑:程序博客网 时间:2024/06/05 01:16

给出迷宫的结点,和迷宫结点处朝向与行走方向的限制关系,求从入口走到出口的最短路径。

最短路问题BFS,用三位数组d[maxn][maxn][4]记录是否经过,结构体数组p[maxn][maxn][4]记录上一步的位置,达到出口就打印解。

#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<vector>#include<queue>using namespace std;const int maxn=12;const char* dirs="NESW";const char* turns="FLR";const int dr[]={-1,0,1,0};const int dc[]={0,1,0,-1};int r0,c0,r1,c1,r2,c2,rx,cx,dir,dirx,turnx,d[maxn][maxn][4];bool has_edge[maxn][maxn][4][4];string s,s0;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];int dir_id(char c){    return (int)(strchr(dirs,c)-dirs);}int trun_id(char c){    return (int)(strchr(turns,c)-turns);}Node walk(const Node& u,int turn){    int dir=u.dir;    if(turn==1) dir=(dir+3)%4;    if(turn==2) dir=(dir+1)%4;    return Node(u.r+dr[dir],u.c+dc[dir],dir);}bool inside(int x,int y){    return (x>0&&x<10&&y>0&&y<10);}void print_ans(Node u){    vector<Node>nodes;    while(1){        nodes.push_back(u);        if(!d[u.r][u.c][u.dir]) break;        u=p[u.r][u.c][u.dir];    }    nodes.push_back(Node(r0,c0,dir));    int cnt=0;    for(int i=(int)nodes.size()-1;i>=0;i--){        if(cnt%10==0) printf(" ");        printf(" (%d,%d)",nodes[i].r,nodes[i].c);        if(++cnt%10==0) printf("\n");    }    if(nodes.size()%10) printf("\n");}void solve(){    queue<Node>q;    memset(d,-1,sizeof(d));    Node u(r1,c1,dir);    d[u.r][u.c][u.dir]=0;    q.push(u);    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]&&inside(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);            }        }    }    printf("  No Solution Possible\n");    return;}bool read(){    cin>>s0;    if(s0=="END") return false;    cout<<s0<<endl;    memset(has_edge,0,sizeof(has_edge));    memset(p,0,sizeof(p));    cin>>r0>>c0>>s>>r2>>c2;    for(int i=0;i<4;i++)        if(s[0]==dirs[i]){            dir=i;            break;        }    r1=r0+dr[dir];    c1=c0+dc[dir];    while(cin>>rx&&rx){        cin>>cx;        while(cin>>s){            if(s=="*") break;            for(int i=0;i<4;i++)                if(s[0]==dirs[i]){                    dirx=i;                    break;                }            for(int i=1;i<s.size();i++){                for(int j=0;j<3;j++)                    if(s[i]==turns[j]){                        turnx=j;                        break;                    }                has_edge[rx][cx][dirx][turnx]=true;            }        }    }    return true;}int main(){    while(read()){        solve();    }    return 0;}


0 0