1215. 脱离地牢

此题有个巨大的吐槽的地方就是最终状态的判定有两种情况,相遇或者到一个格子里,不要忘记当队列为空要判定状态为结束。还有可以用方向来代表数组的下标,是代码更具有可读性。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

int const maxn = 50;
char map[maxn][maxn];
int vis[maxn][maxn][maxn][maxn];
int r,c;
int dr1[] = {-1,1,0,0};
int dc1[] = {0,0,-1,1};
char dre[6];
int dr2[4],dc2[4];
struct point {
    int r1,c1,r2,c2;
    int val;
    point (int aa=0,int bb=0,int aaa=0,int bbb=0,int cc=0):r1(aa),c1(bb),r2(aaa),c2(bbb),val(cc){}
}p1;

bool isin(const point& tmp) {
    return tmp.r1>0&&tmp.r1<=r&&tmp.r2>0&&tmp.r2<=r&&tmp.c1>0&&tmp.c1<=c&&tmp.c2>0&&tmp.c2<=c;
}
bool isend(const point& tmp) {
    return tmp.r1==tmp.r2&&tmp.c1==tmp.c2;
}
void f() {
    for (int i=0;i<4;i++) {
        if(dre[i]=='N') {
            dr2[i]=-1;
            dc2[i]=0;
        }
        if (dre[i]=='S') {
            dr2[i]=1;
            dc2[i]=0;
        }
        if (dre[i]=='W') {
            dr2[i]=0;
            dc2[i]=-1;
        }
        if (dre[i]=='E') {
            dr2[i]=0;
            dc2[i]=1;
        }
    }
}

int bfs() {
    queue<point> Q;
    Q.push(p1);
    while(!Q.empty()) {
        point tmp = Q.front();
        Q.pop();
       if(tmp.val>=256) return -1;
        for (int i=0;i<4;i++) {
            int nr1=tmp.r1+dr1[i];
            int nc1=tmp.c1+dc1[i];
            int nr2=tmp.r2+dr2[i];
            int nc2=tmp.c2+dc2[i];
            if (map[nr2][nc2]=='#') {
                    nr2 = tmp.r2;
                    nc2 = tmp.c2;
                }
            point pp(nr1,nc1,nr2,nc2,tmp.val+1);    
            if(isin(pp)&&map[nr1][nc1]=='.'&&map[nr2][nc2]!='!'&&!vis[nr1][nc1][nr2][nc2]) {
                if((nr1==nr2&&nc1==nc2)||(nr1==tmp.r2&&nr2==tmp.r1&&nc1==tmp.c2&&nc2==tmp.c1)) return tmp.val+1;
                vis[nr1][nc1][nr2][nc2]=1;
                Q.push(point(nr1,nc1,nr2,nc2,tmp.val+1));

            }
        }
    }
    return  -1;
}


int main() {
     while(cin>>r>>c) {
        memset(vis,0,sizeof(vis));
     for (int i=1;i<=r;i++) 
      for (int j=1;j<=c;j++) {
        cin>>map[i][j];
        if(map[i][j]=='P') {
            p1.r1=i; p1.c1=j;
            map[i][j]='.';
        }
        if (map[i][j]=='H') {
            p1.r2=i; p1.c2=j;
            map[i][j]='.';
        }
      }
      vis[p1.r1][p1.c1][p1.r2][p1.c2]=1;
      cin>>dre;
      f();
      int ans = bfs();
      if(ans!=-1) cout<<ans<<endl;
      else cout<<"Impossible"<<endl;
}
}
//方向容易编码错误,题意的理解也容易发生错误。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值