题意
在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(); } }