题意
在x,y坐标系,有流星会落下来,给出每颗流星落下来的坐标和时间,问你能否从(0,0)这个点到一个安全的位置。所谓的安全位置就是不会有流星落下的位置。
题解:
广搜,但是这里有一个深坑,就是搜索的时候判断坐标是否越界的时候,题中说0≤x≤300,0≤y≤300。也就是说如果 if(x>300||y>300||x<0||y<0) 就是越界,不用进队列。
注意,就是这个 x>300||y>300 越界条件有问题。不能是300,要比300大,哪怕301也行。
下面看我调试了5个小时的AC代码,才发现这个神坑...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX=305;
typedef struct node
{
node()
{
x=y=time=0;
}
int x,y;
int time;
}Node;
int mmap[MAX][MAX]; //地图
int dx[4]={-1,1,0,0}; //方向控制
int dy[4]={0,0,-1,1};
int flag[MAX][MAX]; //标记位
queue<Node> q;
void bfs()
{
memset(flag,0,sizeof(flag));
while(!q.empty()) q.pop();
Node s; //把原点入队
s.x=0;
s.y=0;
s.time=0;
q.push(s);
flag[0][0]=1;
Node now;
while(!q.empty())
{
Node cur=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int xx=cur.x+dx[i];
int yy=cur.y+dy[i];
if(xx<0||yy<0||xx>301||yy>301) //就是这里,妈的可坑了,题意明明说<=300,也就是说>300不行,他妈的非要>301才能过,那不就是<=301了?
continue;
now.x=xx;
now.y=yy;
now.time=cur.time+1;
if(mmap[now.x][now.y]==-1) //找到安全地点
{
cout<<now.time<<endl;
return;
}
if(flag[now.x][now.y]==0) //如果没有被走过
{
if(now.time<mmap[now.x][now.y]||mmap[now.x][now.y]==-1) //如果当前地点是安全地点或者还没有被流星炸毁
{
flag[now.x][now.y]=1;
q.push(now);
}
}
}
}
cout<<-1<<endl;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(mmap,-1,sizeof(mmap)); //地图初始化为-1
for(int i=0; i<n; i++) //输入地图信息
{
int x,y,t;
scanf("%d%d%d",&x,&y,&t);
if(mmap[x][y]!=-1) //但要注意的是如果当前流星的坠地时间大于以前的流星的坠地时间,要取最小值
mmap[x][y]=min(mmap[x][y],t);
else
mmap[x][y]=t;
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx<0||yy<0||xx>301||yy>301) //还有这里也是
continue;
if(mmap[xx][yy]!=-1) //这个也是,要取最小坠地时间
mmap[xx][yy]=min(mmap[xx][yy],t);
else mmap[xx][yy]=t;
}
}
if(mmap[0][0]==0) //如果在原点就被炸
cout<<-1<<endl;
else
bfs();
}
}