hdu 1072 Nightmare(BFS)

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

题目大意:逃出迷宫,有6秒的时间限制,但是可以通过到达4点来重置时间回到6秒,求最短时间。不能逃出输出-1.

题目思路:算最短时间,用宽度优先搜索,由于4点可以重复到达,因此不能直接标记所有走过的点。但是重复到达4点是没有意义的,所以每个位置的4点最多经过1次,走过之后把它标记为墙就行了,不然会超内存。

AC代码:

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
const int MAXN = 12;
int mp[MAXN][MAXN];
int vis[MAXN][MAXN][MAXN];
int d[MAXN][MAXN];
struct node{
    int x,y,t,dis;
};
queue<node> q;
int sx,sy,ex,ey;
int n,m;

int C(int x,int y,int t){
    if(x>=0 && x<n && y>=0 &&y<m && mp[x][y]!=0 && !vis[x][y][t])
        return 1;
    return 0;
}

int solve(){
    memset(d,0,sizeof(d));
    memset(vis,0,sizeof(vis));
    while(!q.empty()) q.pop();
    q.push((node){sx,sy,6,0});
    while(!q.empty()){
        node now=q.front();q.pop();
        vis[now.x][now.y][now.t]=1;
        for(int i=0;i<4;i++){
            int dx=now.x+dir[i][0];
            int dy=now.y+dir[i][1];
            int tmp=now.t-1;
            if(C(dx,dy,tmp)&& tmp>0){
                d[dx][dy]=d[now.x][now.y]+1;
                if(mp[dx][dy]==1 && tmp>0){
                    q.push((node){dx,dy,tmp,d[dx][dy]});
                }else if(mp[dx][dy]==3 && tmp>0){
                    return d[dx][dy];
                }else if(mp[dx][dy]==4 && tmp>0){
                    q.push((node){dx,dy,6,d[dx][dy]});
                    mp[dx][dy]=0;
                }
            }
        }
    }
    return -1;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%d",&mp[i][j]);
                if(mp[i][j]==2){
                    sx=i;
                    sy=j;
                }
            }
        }
        printf("%d\n",solve());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Rainbow_storm/article/details/84530716