题目链接:http://poj.org/problem?id=3669
这道题跟我其实有很深的渊源呀,第一次做的时候用的是模拟法,就是对流星下落的时间进行排序,然后模拟每个流星下落的过程,以及人的运动,十分繁琐,经过了WA,RE,最后一直TLE过不了...... 之后放了有一个月,这几天又拿出来,想了一个更简洁的方法,最后AC掉。
思路:先将Map初始化为INF,然后将每颗流星下落的时间标记在Map上,对于同一位置多颗流星撞击,取其中的最小值,然后从起始位置进行宽度优先搜索,直到找到位置上为INF位置。
这道题同时也体现出细节的力量,BFS中有一个细节,就是判断当前状态是否是INF状态,
一种是在从队列中取出状态的时候,
while(que.size()){
Bes=que.front();
que.pop();
if(Map[Bes.x][Bes.y]==INF) return Bes.t;
Map[Bes.x][Bes.y]=0;
for(int i=0;i<4;i++){
iii mid;
mid.x=Bes.x+dir[i][0];
mid.y=Bes.y+dir[i][1];
mid.t=Bes.t+1;
if(mid.t<Map[mid.x][mid.y]) que.push(mid);
}
}
一种是在加入队列之前,
while(que.size()){
Bes=que.front();
que.pop();
for(int i=0;i<4;i++){
iii mid;
mid.x=Bes.x+dir[i][0];
mid.y=Bes.y+dir[i][1];
mid.t=Bes.t+1;
if(Map[mid.x][mid.y]==INF) return mid.t;
if(Map[mid.x][mid.y]<=mid.t) continue;
Map[mid.x][mid.y]=0;
que.push(mid);
}
}
这两种不同的方法在运行时间上相差很大,不知道是题的原因还是本身就存在差异,我先是用的第一种方法,结果一直是TLE,感觉实在无解,去搜了题解直到了第二种方法,结果94ms就过了~~~~
还有一些细节见code了
code:
//poj 3669
//广度优先搜索
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define SIZE 405//注意范围,题目给的范围是流星的范围并不是活动的范围,所以数组应该开得更大一些
#define INF 10000000
struct NODE
{
int x,y,t;
};
typedef struct NODE iii;
int Map[SIZE][SIZE];
int dir[5][2]={{0,1},{0,-1},{-1,0},{1,0},{0,0}}; //表示上 下 左 右 中五个方向
queue<iii> que;// 在此申请了一个iii类型的队列
iii Bes;
void initial()
{
for(int i=0;i<SIZE;i++){
for(int j=0;j<SIZE;j++){
//为了防止出界 将活动区域之外 又围了一圈
if(!i||!j||(i==SIZE-1)||(j==SIZE-1)) Map[i][j]=0;
else Map[i][j]=INF;
}
}
Bes.x=1;//因为活动区域的变化 所以其实位置也得变化
Bes.y=1;
Bes.t=0;
que.push(Bes);
int midx,midy,midt,N; //用于输入时对地图的处理
scanf("%d",&N);
while(N--){
scanf("%d%d%d",&midx,&midy,&midt);
midx++;//为了防止越界 全部都是x,y都是从1开始的
midy++;
for(int i=0;i<5;i++){
if(Map[midx+dir[i][0]][midy+dir[i][1]]>midt){
Map[midx+dir[i][0]][midy+dir[i][1]]=midt;
}
}
}
return ;
}
int BFS()
{
if(Map[1][1]==0) return -1;
if(Map[1][1]==INF) return 0;
while(que.size()){
Bes=que.front();
que.pop();
for(int i=0;i<4;i++){
iii mid;
mid.x=Bes.x+dir[i][0];
mid.y=Bes.y+dir[i][1];
mid.t=Bes.t+1;
if(Map[mid.x][mid.y]==INF) return mid.t;
if(Map[mid.x][mid.y]<=mid.t) continue;
Map[mid.x][mid.y]=0;
que.push(mid);
}
}
return -1;
}
int main()
{
initial();
printf("%d\n",BFS());
return 0;
}