POJ-3669 Meteor Shower(bfs)
http://poj.org/problem?id=3669
注意理解题意:有m颗行星将会落在方格中(第一象限),第i颗行星在ti时间会摧毁(xi,yi)这个点和四周相邻的点,一个人开始在原点,然后只能在第一象限内行走,每单位时间移动一格,只能移动到当前未摧毁的点,问多少时间能到达安全地方。
开始题意理解错了,没有明白每一颗行星最多摧毁5个点,我们可以预处理出被行星摧毁的点,然后用bfs搜索。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 //#include <map> 15 #include <queue> 16 17 #define CL(arr, val) memset(arr, val, sizeof(arr)) 18 19 #define ll long long 20 #define inf 0x7f7f7f7f 21 #define lc l,m,rt<<1 22 #define rc m + 1,r,rt<<1|1 23 #define pi acos(-1.0) 24 25 #define L(x) (x) << 1 26 #define R(x) (x) << 1 | 1 27 #define MID(l, r) (l + r) >> 1 28 #define Min(x, y) (x) < (y) ? (x) : (y) 29 #define Max(x, y) (x) < (y) ? (y) : (x) 30 #define E(x) (1 << (x)) 31 #define iabs(x) (x) < 0 ? -(x) : (x) 32 #define OUT(x) printf("%I64d\n", x) 33 #define lowbit(x) (x)&(-x) 34 #define Read() freopen("a.txt", "r", stdin) 35 #define Write() freopen("dout.txt", "w", stdout); 36 #define maxn 1000000000 37 #define N 1010 38 using namespace std; 39 40 int dir[5][2]={-1,0,1,0,0,1,0,-1,0,0}; 41 int vis[500][500]; 42 struct node 43 { 44 int x,y,time; 45 }; 46 47 int bfs() 48 { 49 if(vis[0][0]==-1) return 0; 50 node p; 51 p.x=p.y=p.time=0; 52 queue<node>que; 53 que.push(p); 54 while(que.size()) 55 { 56 node q=que.front(); 57 que.pop(); 58 for(int i=0;i<4;i++) 59 { 60 p=q; 61 p.x=q.x+dir[i][0]; 62 p.y=q.y+dir[i][1]; 63 p.time++; 64 if(p.x<0||p.y<0) continue; //出界了 65 if(vis[p.x][p.y]==-1) return p.time; //到达安全地方 66 if(p.time<vis[p.x][p.y]) //当前这个点还未摧毁 67 { 68 vis[p.x][p.y]=p.time; //必须赋值,不然会超时,这样可以防止往回走的情况,节省不必要的搜索 69 que.push(p); 70 } 71 } 72 } 73 return -1; 74 } 75 int main() 76 { 77 //freopen("a.txt","r",stdin); 78 int m,x,y,t; 79 scanf("%d",&m); 80 memset(vis,-1,sizeof(vis)); 81 while(m--) 82 { 83 scanf("%d%d%d",&x,&y,&t); 84 for(int i=0;i<5;i++) 85 { 86 int xx=x+dir[i][0]; 87 int yy=y+dir[i][1]; 88 if(xx>=0&&yy>=0) //预处理所有被摧毁的点,并赋值为被摧毁的最小时间。 89 { 90 if(vis[xx][yy]==-1) vis[xx][yy]=t; 91 else vis[xx][yy]=min(t,vis[xx][yy]); 92 } 93 } 94 } 95 if(vis[0][0]==0) printf("-1\n"); 96 else printf("%d\n",bfs()); 97 return 0; 98 }