UVA10047四维bfs

本文探讨了如何使用四维BFS算法解决带有方向和颜色限制的迷宫问题,通过广度优先搜索找到从起点到终点的最短路径,并详细解释了算法原理及实现过程。

本来是小白书上面给的习题,神奇的变成了大白书上例题。

其实就是一个四维的bfs,因为每个格子多了俩个状态,即方向和颜色,

另外bfs搜索最短路的原理是根据搜到的下一个格子是上一个格子距离加一来算的,

因为是宽搜,所以一旦搜到要到达的点,则那个点存的距离即使到那个点的最短距离,

而这个题,当它在原本的格子里不动的时候即为一个状态,时间即加一,但是格子距离并不加一,

所以和bfs搜索最短路的原理是一样的,可以bfs来做。

另外注意最后那个回车是在俩个样例之间,不是每个后面都有。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<map>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
const int color=5;
const int dir=4;
int m,n;
char grid[30][30];
int vis[30][30][dir][color];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct node
{
    int x,y,d,c,step;
    node(int x,int y,int d,int c,int step):x(x),y(y),d(d),c(c),step(step) {}
};
int bx,by,ex,ey;
int bfs()
{
    memset(vis,0,sizeof(vis));
    queue<node> q;
    q.push(node(bx,by,0,0,0));
    vis[bx][by][0][0]=1;
    while(!q.empty())
    {
        node pre=q.front();
        q.pop();
        if(pre.x==ex&&pre.y==ey&&pre.c==0) return pre.step;
        for(int d=0;d<4;d++)
        {
            if(d==pre.d)
            {
                int x=pre.x+dx[d];
                int y=pre.y+dy[d];
                int c=(pre.c+1)%color;
                int s=pre.step+1;
                if(x<0||x>=m||y<0||y>=n)
                continue;
                if(grid[x][y]=='#'||vis[x][y][d][c])
                    continue;
                vis[x][y][d][c]=1;
                q.push(node(x,y,d,c,s));
            }
            else if((pre.d+1)%dir==d||(pre.d-1+dir)%dir==d)
            {
                if(vis[pre.x][pre.y][d][pre.c]) continue;
                vis[pre.x][pre.y][d][pre.c]=1;
                q.push(node(pre.x,pre.y,d,pre.c,pre.step+1));
            }
        }
    }
    return -1;
}
int main()
{
    int cas=0;
    while(cin>>m)
    {
        cin>>n;
        if(!m&&!n) break;
       // getchar();
        cas++;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                 cin>>grid[i][j];
                 if(grid[i][j]=='S')
                 {
                     bx=i;
                     by=j;
                 }
                 if(grid[i][j]=='T')
                 {
                     ex=i;
                     ey=j;
                 }
            }
    //    for(int i=0;i<m;i++)
    //    {
     //       for(int j=0;j<n;j++)
    //            cout<<grid[i][j];
    //        cout<<endl;
     //   }
   //     cout<<bx<<' '<<by<<' '<<ex<<' '<<ey<<endl;
        int ans=bfs();
        if(cas-1!=0) cout<<endl;
        printf("Case #%d\n",cas);
        if(ans == -1) printf("destination not reachable\n");
        else printf("minimum time = %d sec\n",ans);
        //cout<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值