此題的意思讓我難受,因爲描述的很不清晰,而且數據也有問題,首先大致題意就是在一個地方會隕落流星,然後隕落的地方在座標系的第一象限,當隕石砸中一個點,其不但會破壞被砸中點,還會破壞以被砸中點爲中心的上下左右一共5個點,且它們砸落的時間不一,題目的輸入就是第一行給定要砸多少隕石,然後接下來就是描述隕石砸落座標和砸落時間,然後你會從座標原點出發去尋找一個隕石砸不到的位置,你所能到的點只能是隕石還沒破壞的點,你每移動一次耗時一個單位時間,問找到最短安全位置的步數,如果找不到輸出-1.
此題——我 TM Runtime Error 了8次,都怪自己蠢,搜索bfs時判了訪問點是否越界,但輸入卻沒判,然後一直在懷疑是自己搜索越的界,還是隊友幫忙看來的。。。。我的思路就是起先全圖賦值-1,然後輸入隕石墜落點時,將該點賦值,負的值就是隕石砸落時間,並將其四周四個點也賦值,當某個被破壞點被多次破壞時,賦值最早破壞的時間,然後從原點開始搜索,每移一步,步數加1,當訪問點爲-1(表示不會被破壞)或訪問點值比步數大(表示現在還沒被破壞),表示可以訪問,然後對訪問點爲-1就直接終止搜索,返回步數。
此題的坑還不少,首先題目說好的第一象限,結果數據隕石砸到了座標軸上,而且說好的範圍是[0,300],結果數據過了300,,還有就是訪問過的點要標記一下,不要再次訪問,貌似多次重複訪問會TL。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int mov1[4]= {0,1,0,-1};
int mov2[4]= {1,0,-1,0};
struct node
{
int x;
int y;
int num;
node()
{
x=0;
y=0;
num=0;
}
node(int a,int b,int c)
{
x=a;
y=b;
num=c;
}
};
int mp[505][505]= {0};
bool vis[505][505]= {0};
queue<node> q;
node nd;
bool flag=0;
void bfs()
{
flag=0;
while(!q.empty())q.pop();
nd.x=0;
nd.y=0;
nd.num=0;
if(mp[0][0]==-1)
{
flag=1;
return ;
}
else if(mp[0][0]==0)return ;
q.push(nd);
vis[nd.x][nd.y]=1;
while(!q.empty())
{
nd=q.front();
q.pop();
if(mp[nd.x][nd.y]==-1)
{
flag=1;
break;
}
for(int i=0; i<4; i++)
{
int x=nd.x+mov1[i];
int y=nd.y+mov2[i];
if(x<0||y<0||vis[x][y]==1)continue;
int z=nd.num+1;
if(mp[x][y]==-1||mp[x][y]>z)
{
q.push(node(x,y,z));
vis[x][y]=1;
}
}
}
return ;
}
int main()
{
//freopen("in.in","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
memset(mp,-1,sizeof(mp));
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++)
{
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
if(mp[x][y]==-1||mp[x][y]>z)
mp[x][y]=z;
for(int i=0; i<4; i++)
if(x+mov1[i]>=0&&y+mov2[i]>=0)//要判斷是否越界,起初就是在這裏跪到爽
if(mp[x+mov1[i]][y+mov2[i]]==-1||mp[x+mov1[i]][y+mov2[i]]>z)
mp[x+mov1[i]][y+mov2[i]]=z;
}
/*for(int j=5;j>=0;j--)
{
for(int i=0;i<=5;i++)
printf("%d ",mp[i][j]);
printf("\n");
}*/
bfs();
if(flag)
printf("%d\n",nd.num);
else
printf("-1\n");
}
return 0;
}