hdu 1180

10 篇文章 0 订阅
10 篇文章 0 订阅

主题思想 : BFS ,这里有个注意的情况是除了上下左右可以走,也可以不走即可以停留,所以需要把地图上可以停留的点,单独在push进队列。
再一个注意的点就是,当是楼梯时,是根据刚到达的时间,进行变向的,也就是说,到达楼梯需要爬的时间,正好是上一步结束的时间。

AC代码:

#include <iostream>
#include<cstdio>
#include<queue>
#include<string>
#include<cstring>

using namespace std;

const int maxn=25;

char g[maxn][maxn];

bool visited[maxn][maxn];

int dir[4][2]={0,1,0,-1,1,0,-1,0}; // r,l,d,u
int n,m;

int sx,sy;
int ex,ey;

struct status{

    int x,y;
    int step;
    status(int x,int y,int step):x(x),y(y),step(step){}
};

status change(status pre,int dir, char c,int step){

    if(step%2)
        c=(c=='|'?'-':'|');


     if(c=='|'){

       if(dir==2) return status(pre.x+1,pre.y,0);
       if(dir==3) return status(pre.x-1,pre.y,0);
       else return status(-1,-1,0);

     }else if(c=='-'){
        if(dir==0) return status(pre.x,pre.y+1,0);
        if(dir==1) return status(pre.x,pre.y-1,0);
        else return status(-1,-1,0);

     }
}
int bfs(){


    memset(visited,false,sizeof(visited));

    queue<status> q;
    while(!q.empty()) q.pop();
    q.push(status(sx,sy,0));
    visited[sx][sy]=true;

    int xx,yy;
    while(!q.empty()){

         status now=q.front();
         q.pop();

        for(int i=0;i<4;i++){
            xx=now.x+dir[i][0];
            yy=now.y+dir[i][1];

            //out of range
            if(xx>=m||xx<0||yy>=n||yy<0||visited[xx][yy]||g[xx][yy]=='*')continue;
            //if find the target
            if(xx==ex&&yy==ey){
                return now.step+1;
            }

            if(g[xx][yy]=='|'||g[xx][yy]=='-'){
                // the import is the step is now.step
               status next=change(status(xx,yy,0),i,g[xx][yy],now.step);
               xx=next.x;
               yy=next.y;
            }
             if(xx>=m||xx<0||yy>=n||yy<0||visited[xx][yy]||g[xx][yy]=='*')continue;

            if(xx==ex&&yy==ey) return now.step+1;

            q.push(status(xx,yy,now.step+1));
            visited[xx][yy]=true;
        }
        q.push(status(now.x,now.y,now.step+1));
    }
    return 0;
}


int main()
{

    string s;
    while(scanf("%d%d",&m,&n)!=EOF){

        //m rows ,n columns

        sx=sy=-1;
        ex=ey=-1;

        for(int i=0;i<m;i++){

           scanf("%s",g[i]);

         //  printf("%s\n",g[i]);
            for(int j=0;j<n;j++){
                if(g[i][j]=='S'){
                    sx=i;
                    sy=j;
                }else if(g[i][j]=='T'){
                    ex=i;
                    ey=j;
                }
            }
        }

        if(m*n<2||sx==-1||ex==-1){
            printf("0\n");
            continue;
        }
        int ans=0;
        ans=bfs();
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值