hdu 5040 Instrusive (bfs)

来源:互联网 发布:淘宝安全证书过期 编辑:程序博客网 时间:2024/05/24 15:43

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5040

题意:给出一个棋盘图,给出起点,终点,和守卫的位置,每个守卫有东南西北的初始朝向,每个守卫的防守范围是两格(自身所在区域算一个),每过1秒钟,所有守卫的所朝方向都会顺时针旋转90度,从被监视位置到其他的任何位置都需要消耗3秒钟,从其他位置进入被监视位置需要3秒钟,其他的情况消耗1秒钟,当处于被监视位置时也可以停留若干秒,等处于非监视状态再继续,问从起点到终点的最短时间。

思路:

基本思路bfs,然后根据根据时间%4的结果,将图分成四份,每次从当前点进行扩展时,先判断当前所在点的状态是否被监视,据从再扩展到其他状态,如果处于被监视的状态,再分出一个原地不动的状态。

感觉这道题目就是要成分理解题意,然后代码敲的稳一点,姿势好一点就能A掉了。

code:

//hdu 5040 (bfs~)#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <queue>#define INF 1e9using namespace std;const int maxn=550;struct ppp{    int x,y,ti;    bool operator < (const ppp&a) const{        return ti>a.ti;    }};char cc[maxn][maxn];int vis[maxn][maxn][4],N;int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};    //up down left rightbool judge(int x,int y){    if(x<0||y<0||x>=N||y>=N) return false;    if(cc[x][y]=='#') return false;    return true;}int cal(int x,int y,int time){    if(cc[x][y]=='N'||cc[x][y]=='S'||cc[x][y]=='E'||cc[x][y]=='W') return 0;    for(int i=0;i<4;i++){        int mx=x+dir[i][0],my=y+dir[i][1];        if(!judge(mx,my)) continue;        if(cc[mx][my]=='N'){            //printf("N.\n");            int d=(0+time)%4;            if(abs(d-i)==2) return 1;        }        else if(cc[mx][my]=='E'){            //printf("E.\n");            int d=(1+time)%4;            if(abs(d-i)==2) return 1;        }        else if(cc[mx][my]=='S'){            //printf("S.\n");            int d=(2+time)%4;            if(abs(d-i)==2) {                //printf("S.time=%d i=%d cc=%c\n",time,i,cc[x][y]);                return 1;            }        }        else if(cc[mx][my]=='W'){           // printf("W.\n");            int d=(3+time)%4;            if(abs(d-i)==2) return 1;        }    }    return -1;}void bfs(int sx,int sy){    int ans=INF;    bool flag;    priority_queue<ppp> que;    ppp P;    P.x=sx;    P.y=sy;    P.ti=0;    que.push(P);    while(que.size()){        P=que.top(); que.pop();        if(cc[P.x][P.y]=='T'){            ans=min(ans,P.ti);            break;        }        for(int i=0;i<4;i++){            int mx=P.x+dir[i][0],my=P.y+dir[i][1];            if(!judge(mx,my)) continue;            ppp midP;            midP.x=mx; midP.y=my; midP.ti=P.ti;            int tt=cal(P.x,P.y,P.ti),mtt=cal(midP.x,midP.y,P.ti);            if(tt==0){                midP.ti+=3;            }            else if(tt==1){                midP.ti+=3;                ppp midP2=P;                midP2.ti++;                if(midP2.ti<vis[midP2.x][midP2.y][midP2.ti%4]){                    vis[midP2.x][midP2.y][midP2.ti%4]=midP2.ti;                    que.push(midP2);                }            }            else if(tt==-1){                //printf(".-1.\n");                if(mtt==0) midP.ti+=3;                else if(mtt==1){                    ppp midP2=P;                    midP2.ti++;                    if(midP2.ti<vis[midP2.x][midP2.y][midP2.ti%4]){                        vis[midP2.x][midP2.y][midP2.ti%4]=midP2.ti;                        que.push(midP2);                    }                    midP.ti+=3;                }                else midP.ti++;            }            if(midP.ti<vis[midP.x][midP.y][midP.ti%4]){                vis[midP.x][midP.y][midP.ti%4]=midP.ti;                que.push(midP);            }        }    }    if(ans==INF) printf("-1\n");    else printf("%d\n",ans);}int main(){    int T;    scanf("%d",&T);    for(int kk=1;kk<=T;kk++){        scanf("%d",&N);        for(int i=0;i<N;i++) scanf("%s",cc[i]);        for(int i=0;i<N;i++) for(int j=0;j<N;j++) for(int k=0;k<4;k++) vis[i][j][k]=INF;        printf("Case #%d: ",kk);        for(int i=0;i<N;i++){            int j;            for(j=0;j<N;j++) if(cc[i][j]=='M'){bfs(i,j);break;}            if(cc[i][j]=='M') break;        }    }    return 0;}


0 0
原创粉丝点击