【BFS】 HDU 4528 小明系列故事——捉迷藏

原题直通车:HDU 4528 小明系列故事——捉迷藏

分析: 标记时加两种状态就行.

代码:

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

const int maxn=101;
char f[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
bool vis[maxn][maxn][2][2];
int n,m,k,ei,ej,di,dj,si,sj;
struct node{
    int x,y,time,p,q;
}rt,ne;
void work(node &rt){
    bool u;
    if(!rt.p&&rt.x==ei){
        int a=min(rt.y,ej), b=max(rt.y,ej);
        u=false;
        for(int i=a+1;i<b;++i)
            if(f[ei][i]!='.') u=true;
        if(!u)rt.p=1;
    }
    if(!rt.p&&rt.y==ej){
        int a=min(rt.x,ei), b=max(rt.x,ei);
        u=false;
        for(int i=a+1;i<b;++i)
            if(f[i][ej]!='.') u=true;
        if(!u)rt.p=1;
    }
    if(!rt.q&&rt.x==di){
        int a=min(rt.y,dj), b=max(rt.y,dj);
        u=false;
        for(int i=a+1;i<b;++i)
            if(f[di][i]!='.')u=true;
        if(!u)rt.q=1;
    }
    if(!rt.q&&rt.y==dj){
        int a=min(rt.x,di), b=max(rt.x,di);
        u=false;
        for(int i=a+1;i<b;++i)
            if(f[i][dj]!='.') u=true;
        if(!u)rt.q=1;
    }
}
int BFS(){
    queue<node>M;
    rt.x=si, rt.y=sj, rt.time=0, rt.p=0, rt.q=0;
    vis[si][sj][0][0]=true;
    M.push(rt);
    while(!M.empty()){
        rt=M.front(); M.pop();
        work(rt);
        if(rt.p&&rt.q) return rt.time;
        for(int i=0;i<4;++i){
            ne=rt; ne.x+=dx[i]; ne.y+=dy[i]; ne.time+=1;
            if(ne.x<0||ne.x>=n||ne.y<0||ne.y>=m||ne.time>k||f[ne.x][ne.y]!='.') continue;
            if(!vis[ne.x][ne.y][ne.p][ne.q]){
                M.push(ne);
                vis[ne.x][ne.y][ne.p][ne.q]=true;
            }
        }
    }
    return -1;
}
int main(){
    int T,i,j,t,u,cas=1; scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&k);
        for(i=0;i<n;++i){
            scanf("%s",f[i]);
            for(j=0;j<m;++j){
                if(f[i][j]=='S') si=i, sj=j,f[i][j]='.';
                if(f[i][j]=='E') ei=i, ej=j;
                if(f[i][j]=='D') di=i, dj=j;
                for(t=0;t<2;++t)
                    for(u=0;u<2;++u)
                        vis[i][j][t][u]=false;
            }
        }
        printf("Case %d:\n%d\n",cas++,BFS());
    }
    return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值