hdu1072

特点:
1:走过的路不能标记,因为等会可能还会走(当需要增加距离爆炸时间的时候)
2: 在没有对顶点做标记的情况下,需要通过将访问过了的4标记为0,以减小搜索范围,
    这样才能跳出while(!Q.empty())循环
3: 队列里的时间不是从大到小的,因为4位置会改变时间,比如6,4,2,在遇到4时
    会变成6,4,2,6,(见标记2)

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
int m,n,s[10][10],sx,ex,sy,ey;
struct node
{
    int x,y,time,step;
};
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void BFS()
{
    int i,k,j;
    queue<node>Q;
    node p,q;
    p.x=sx;
    p.y=sy;
    p.step=6;//表示炸弹剩余时间
    p.time=1;//表示已使用时间
    Q.push(p);
    while(!Q.empty())
    {
        q=Q.front();
        Q.pop();
      //  if (q.step<=0) 由于队列的时间不是递减的,因此不能置于此处,(遇到了4就会改变其值)
      //  break;
        if (q.x==ex&&q.y==ey)
        {
            printf ("%d\n",q.time);
            return;
        }
        for (k=0;k<4;++k)
        {
            p=q;
            p.x+=dir[k][0];
            p.y+=dir[k][1];
            p.step=q.step-1;
            if (p.x>=1&&p.y<=m&&p.y>=1&&p.x<=n&&s[p.x][p.y]!=0&&p.step>0)
            {
                if (s[p.x][p.y]==4)
                {
                    s[p.x][p.y]=0;//到达4,就无需在来一次,因为炸弹剩余时间不会增加
                    p.step=6;
                    p.time=q.time+1;
                }
                if (s[p.x][p.y]==1)
                {
                    p.time=q.time+1;
                }
                    Q.push(p);
            }
        }
    }
    printf ("-1\n");
}
int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for (i=1;i<=n;++i)
        for (j=1;j<=m;++j)
        {
            scanf("%d",&s[i][j]);
            if (s[i][j]==2)
            sx=i,sy=j;
            if (s[i][j]==3)
            ex=i,ey=j;
        }
        BFS();
    }
    return 0;
}

 

posted @ 2013-04-15 10:24  一线添  阅读(140)  评论(0编辑  收藏  举报