`
阿尔萨斯
  • 浏览: 4173181 次
社区版块
存档分类
最新评论

HDU 1072 Nightmare(BFS)

 
阅读更多

HDU 1072 Nightmare(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=1072

题意:有一个N*M的迷宫,你要从起点2走到终点3,且你身上有,这个6分钟后爆炸,你在迷宫中每走一步需要1分钟,且迷宫中有重置装置(4格子),可以使得你的爆炸时间重新变为6.不过不论是你到达终点还是你到达重置装置的地方,你身上的爆炸时间一定要>=1分钟才行,要不你就失败.重置装置可以无限使用,且迷宫中为1的格子是障碍,为0的格子是空(可以走).输出你走到终点的最短时间.

分析:又是一道设计状态的BFS题目,由于题目中每个格子可能重复走(因为要去用重置装备),所以我们设计状态如下:

struct Node

{

int r, c;//当前坐标

int time;//当前还剩time分钟爆炸

intdist;//走到当前r,c,time状态所花的时间(即所走的距离)

}Q[maxn]

所以我们用dist[r][c][time](初值-1,表示该状态还没到达) 表走到状态(r,c,time)所花的最少时间(步数).

因为所有格子都是可以重复走的,但是当我重复走这个格子的时候如果具有一个更大的time,我就可能走得更多的格子,出现不同的结果.所以time要作为状态的一维.如果剩余time更多,当然更好,但是有可能我们剩余time少的状态也可以到达终点且dist可能更少.所以time少的状态我们也不可以抛弃(即我们不能只保存time最大的那个rc)

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=10000+100;
int N,M;
int sr,sc,er,ec;//起点终点坐标
int dist[10][10][10];
int map[10][10];
int dr[]={-1,1,0,0};//上下左右
int dc[]={0,0,-1,1};
struct Node
{
    int r,c,time,dist;
    Node(){}
    Node(int r,int c,int time,int dist):r(r),c(c),time(time),dist(dist){}
}Q[maxn];
int BFS()
{
    memset(dist,-1,sizeof(dist));
    int front=0,tail=1;
    Q[front]=Node(sr,sc,6,0);
    dist[sr][sc][6]=0;
    while(front<tail)
    {
        Node node=Q[front];
        for(int d=0;d<4;d++)
        {
            int nr=node.r+dr[d], nc=node.c+dc[d];
            if(!(nr>=0&&nr<N&&nc>=0&&nc<M) || map[nr][nc]==0) continue;//非法坐标
            int ntime = map[nr][nc]==4?6: (node.time-1);
            int ndist = node.dist+1;
            if(dist[nr][nc][ntime]==-1 || dist[nr][nc][ntime]>ndist)
            {
                dist[nr][nc][ntime]=ndist;
                if(ntime>1) Q[tail++]=Node(nr,nc,ntime,ndist);  //错误,这里没加前面的if,ntime如果==1,它的后继的time肯定为0,没意义
                if(nr==er&&nc==ec) return ndist;  //不用遍历全图,这就是最短的距离
            }
        }
        front++;
    }
    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",&map[i][j]);
            if(map[i][j]==2)
            {
                sr=i, sc=j;
                map[i][j]=1;
            }
            else if(map[i][j]==3)
            {
                er=i, ec=j;
                map[i][j]=1;
            }
        }
        int ans=BFS();
        printf("%d\n",ans);
    }
    return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics