HDU 3137 bfs

从起点到终点的过程中,只能向右或者保持相同的方向行走,所以有可能经过同一个点不止一次,因此在标记为上,与以往不同。

并且,在状态记录中,需要记录当前的方向,从而保证,之后的行走的方向由当前行走的方向所决定。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;

int n,m;
string graph[22];
int sx,sy,ex,ey;

struct node{
    int x,y,to,step;
};

bool vis[5][22][22];
//1 2 3 4  上右下左

int bfs(){
    memset(vis,0,sizeof(vis));
    queue<node> q;
    node cur,tmp;
    tmp.x = sx , tmp.y = sy, tmp.step = 0;   //初始节点为起点
    for(int i=1;i<=4;i++){
        tmp.to = i;
        q.push(tmp);
        vis[i][sx][sy] = 1;
    }
    while(!q.empty()){
        cur = q.front() , q.pop();
        int x1,y1,x2,y2,to;
        x1 = x2 = cur.x;
        y1 = y2 = cur.y;
        if(cur.to==1)
            x1--,y2++,to=2;
        else if(cur.to==2)
            y1++,x2++,to=3;
        else if(cur.to==3)
            x1++,y2--,to=4;
        else if(cur.to==4)
            y1--,x2--,to=1;
        
        if(x1>=0 && x1<n && y1>=0 && y1<m && graph[x1][y1]!='X' && !vis[cur.to][x1][y1]){
            if(x1==ex && y1==ey) return cur.step+1;
            vis[cur.to][x1][y1] = 1;
            tmp.x = x1;
            tmp.y = y1;
            tmp.to = cur.to;
            tmp.step = cur.step+1;
            q.push(tmp);
        }
        if(x2>=0 && x2<n && y2>=0 && y2<m && graph[x2][y2]!='X' && !vis[to][x2][y2]){
            if(x2==ex && y2==ey) return cur.step+1;
            vis[to][x2][y2] = 1;
            tmp.x = x2;
            tmp.y = y2;
            tmp.to = to;
            tmp.step = cur.step+1;
            q.push(tmp);
        }
    }
    return 0;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        getchar();
        for(int i=0;i<n;i++){
            getline(cin,graph[i]);
//            cout<<graph[i]<<endl;
            for(int j=0;j<m;j++){
                if(graph[i][j]=='S')
                    sx = i, sy = j;
                else if(graph[i][j]=='F')
                    ex = i, ey = j;
            }
        }
        printf("%d\n",bfs());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值