Meteor Shower POJ - 3669-BFS


题意:巨大流星雨即将袭来。每个流星会对击中的地方以及周围(上下左右四格)造成破坏。Bessie开始时位于(0, 0)位置,并希望逃到一处不会被袭击到的地方(在第一象限内)。已知每移动一格需要1个时间单位,被流星破坏后的地方不能再进入。给出M个流星在T时刻击中的地方(X, Y),问Bessie能否逃到安全的地方,若能输出最短时间,否则输出-1。

思路:初始化地图,每个点初始化无穷大,再根据输入爆炸时间不断更新最早爆炸时间,然后进行宽度搜索(BFS)。

AC代码:

#include <iostream>
#include <cstdio>
#include<cstring>
#include <iomanip>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include<queue>


using namespace std;
typedef pair <int,int> p;


const int INF = 100000000;


//输入
int n;
int xx[50000], yy[50000],tt[50000];


int mg[401][401];                        //保存地图
int d[401][401];                        //保存最短步数


//4个方向
 int dx[4] = {-1, 1, 0, 0};
 int dy[4] = {0, 0, -1, 1};
 void init()
 {
     //初始化地图每个点爆炸时间为无穷大
     for(int i=0;i<401;i++)
     fill(mg[i],mg[i]+401,INF);//二维矩阵初始化方法2


     //根据输入数据更改地点爆炸时间
     for(int i=0;i<n;i++)
     {
         mg[xx[i]][yy[i]]=min(tt[i],mg[xx[i]][yy[i]]);
     }
     //改动上下左右最小爆照时间
        for(int j=0;j<n;j++)
         for(int k=0;k<4;k++)
         {
             int nx=xx[j]+dx[k];
             int ny=yy[j]+dy[k];
             if(nx>=0&&ny>=0)
                mg[nx][ny]=min(tt[j],mg[nx][ny]);


         }
         //初始化走到每一点步数为无穷大
         for(int i=0;i<401;i++)
            fill(d[i],d[i]+401,INF);
}
int bfs()
{
    if(mg[0][0]==0) return -1;
    queue<p>que;
    que.push(p(0,0));
    d[0][0]=0;
    while(!que.empty())
{
        p l=que.front();
        int x=l.first,y=l.second;
        que.pop();


        if(mg[x][y]==INF) return d[x][y];//如果已到达安全位置(爆炸时间是无穷即不爆炸),返回此时所用步数


        for(int i=0;i<4;i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx>=0&&ny>=0&&d[nx][ny]==INF&&mg[nx][ny]>d[x][y]+1)
            {
                 que.push(p(nx,ny));
                 d[nx][ny]=d[x][y]+1;
            }
        }


}
   return -1;


}
void solve()
{
    int ans=bfs();
    cout<<ans<<endl;
}




 int main()
 {
     scanf("%d",&n);
     for(int i=0;i<n;i++)
     {
         scanf("%d%d%d",&xx[i],&yy[i],&tt[i]);
     }
     init();
     solve();
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值