Meteor Sh
ower
POJ - 3669
Input
Output
Sample Input
4
0 0 2
2 1 2
1 1 2
0 3 5
Sample Output
5
题意:输入一个n,有n组坐标和n个时间,每组坐标将会在t时刻被轰炸,而且他的四个周边坐标也会被轰炸,轰炸时间以及轰炸后都不能行走,现在有一个人在原点,他可以上下左右移动,并且每动一步花费一时刻,问最少多少时间他能走到安全区(只要没被轰炸的地区都是安全区)。
题解:这题用广搜写,先将轰炸区和轰炸区的四周全部标记起来,然后开始广搜,广搜要注意区域被轰炸后无法经过,必须在区域轰炸之前走,直到走到安全区结束。
代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int mp[350][350],book[350][350];
int n,sum,a[4][2]={0,1,1,0,0,-1,-1,0};
struct node
{
int x,y,t;
}q[50005];
int cmp(node A,node B)
{
return A.t<B.t;
}
int bfs()
{
queue<node>e;//定义queue容器
node now,tmp;
now.x=0;
now.y=0;
now.t=0;
e.push(now);//将起点压入队列
book[0][0]=1;
while(!e.empty())
{
now=e.front();
e.pop();//将队首元素出队
if(mp[now.x][now.y]<=now.t)//如果还没走到,这个区域就被轰炸,则无法行走
continue;
for(int i=0;i<4;i++)
{
int tx=now.x+a[i][0];
int ty=now.y+a[i][1];
int tt=now.t+1;
if(tx>=0&&ty>=0&&book[tx][ty]==0&&mp[tx][ty]==-1)//如果是安全区结束搜索
return tt;
else if(tx>=0&&ty>=0&&book[tx][ty]==0&&mp[tx][ty]>tt)//tx,ty的轰炸时间在tt后,可以行走
{
tmp.x=tx;
tmp.y=ty;
tmp.t=tt;
book[tx][ty]=1;
e.push(tmp);
}
}
}
return -1;
}
int main()
{
while(~scanf("%d",&n))
{
int i,j;
for(i=0;i<310;i++)
for(j=0;j<310;j++)
{
mp[i][j]=-1;
book[i][j]=0;
}
for(i=0;i<n;i++)
{
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].t);
}
sort(q,q+n,cmp);//爆炸时间从小到大排序,因为轰炸后的路不能走
for(i=0;i<n;i++)
{
if(mp[q[i].x][q[i].y]==-1)
mp[q[i].x][q[i].y]=q[i].t;
for(j=0;j<4;j++)//将被轰炸的区域的四周也标记为轰炸区
{
int tx=q[i].x+a[j][0];
int ty=q[i].y+a[j][1];
if(tx>=0&&ty>=0&&mp[tx][ty]==-1)
mp[tx][ty]=q[i].t;
}
}
int k=bfs();//广搜
printf("%d\n",k);
}
}
4 0 0 2 2 1 2 1 1 2 0 3 5
5
题意:输入一个n,有n组坐标和n个时间,每组坐标将会在t时刻被轰炸,而且他的四个周边坐标也会被轰炸,轰炸时间以及轰炸后都不能行走,现在有一个人在原点,他可以上下左右移动,并且每动一步花费一时刻,问最少多少时间他能走到安全区(只要没被轰炸的地区都是安全区)。
题解:这题用广搜写,先将轰炸区和轰炸区的四周全部标记起来,然后开始广搜,广搜要注意区域被轰炸后无法经过,必须在区域轰炸之前走,直到走到安全区结束。
代码:
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; int mp[350][350],book[350][350]; int n,sum,a[4][2]={0,1,1,0,0,-1,-1,0}; struct node { int x,y,t; }q[50005]; int cmp(node A,node B) { return A.t<B.t; } int bfs() { queue<node>e;//定义queue容器 node now,tmp; now.x=0; now.y=0; now.t=0; e.push(now);//将起点压入队列 book[0][0]=1; while(!e.empty()) { now=e.front(); e.pop();//将队首元素出队 if(mp[now.x][now.y]<=now.t)//如果还没走到,这个区域就被轰炸,则无法行走 continue; for(int i=0;i<4;i++) { int tx=now.x+a[i][0]; int ty=now.y+a[i][1]; int tt=now.t+1; if(tx>=0&&ty>=0&&book[tx][ty]==0&&mp[tx][ty]==-1)//如果是安全区结束搜索 return tt; else if(tx>=0&&ty>=0&&book[tx][ty]==0&&mp[tx][ty]>tt)//tx,ty的轰炸时间在tt后,可以行走 { tmp.x=tx; tmp.y=ty; tmp.t=tt; book[tx][ty]=1; e.push(tmp); } } } return -1; } int main() { while(~scanf("%d",&n)) { int i,j; for(i=0;i<310;i++) for(j=0;j<310;j++) { mp[i][j]=-1; book[i][j]=0; } for(i=0;i<n;i++) { scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].t); } sort(q,q+n,cmp);//爆炸时间从小到大排序,因为轰炸后的路不能走 for(i=0;i<n;i++) { if(mp[q[i].x][q[i].y]==-1) mp[q[i].x][q[i].y]=q[i].t; for(j=0;j<4;j++)//将被轰炸的区域的四周也标记为轰炸区 { int tx=q[i].x+a[j][0]; int ty=q[i].y+a[j][1]; if(tx>=0&&ty>=0&&mp[tx][ty]==-1) mp[tx][ty]=q[i].t; } } int k=bfs();//广搜 printf("%d\n",k); } }