标签:
http://poj.org/problem?id=3669
题目的大致意思:
1.玩家从原点(0,0)出发
2.有流星在一定时间里往地图上砸。砸到以后,这个点以及上下左右共5个点就再也不能行走了(砸以前可以走)
3.玩家每个单位时间可以上下左右走一格
4.找到最短的行走距离,保证这个点是安全的,即所有流星都不会砸到这个点
牵扯到最短距离,首先想到广度搜索
这里要注意一点:题目规定的X,Y是300,但这是流星下落的位置,所以流星的覆盖范围是301(加上 上下左右),那么玩家可以行走到302,所以静态数组至少要开到302以上才行
1 #include <stdio.h> 2 #include <memory.h> 3 #include <queue> 4 using namespace std; 5 6 #define MAX 302 //地图宽度 7 8 int m; //流星数 9 int map[MAX][MAX]; //地图 10 bool visited[MAX][MAX]; //是否访问过 11 int last; //最晚的流星时间 12 13 int go[][2] = 14 { 15 1, 0, 16 -1, 0, 17 0, 1, 18 0, -1, 19 0, 0 20 }; //5个方向 21 22 struct Meteor 23 { 24 int x; 25 int y; 26 int t; 27 }meteor[50000]; //流星结构,用于输入 28 29 typedef Meteor Node; //节点结构,用于bfs 30 31 int max(int a, int b) 32 { 33 return a > b ? a : b; 34 } 35 36 int bfs() 37 { 38 memset(visited, false, sizeof(visited)); 39 40 queue<Node> q; //队列 41 42 Node fir; //起始点入队 43 fir.x = fir.y = fir.t = 0; 44 visited[0][0] = true; 45 46 q.push(fir); 47 48 while (q.size() > 0) //bfs 49 { 50 Node now = q.front(); 51 q.pop(); 52 53 for (int i = 0; i < 4; i++) //每次必须行动1格 54 { 55 Node tmp = now; 56 tmp.x += go[i][0]; 57 tmp.y += go[i][1]; 58 tmp.t++; 59 60 if (tmp.x >= 0 && tmp.y >= 0 && map[tmp.x][tmp.y]>tmp.t && !visited[tmp.x][tmp.y]) //没越界、流星还未砸这个格子、还没访问过(重复访问就是不是bfs最优解了) 61 { 62 visited[tmp.x][tmp.y] = true; //标记 63 if (map[tmp.x][tmp.y] > last) //如果格子不会被砸到 64 { 65 return tmp.t; 66 } 67 q.push(tmp); 68 } 69 } 70 } 71 return -1; 72 } 73 74 int main() 75 { 76 while (scanf("%d", &m) != EOF) 77 { 78 for (int i = 0; i < m; i++) 79 { 80 scanf("%d %d %d", &meteor[i].x, &meteor[i].y, &meteor[i].t); 81 } 82 83 memset(map, 0x7f, sizeof(map)); //要严谨一点可以用0x7fffffff,不过就不能用memset了 84 for (int i = 0; i < m; i++) 85 { 86 //计算最晚流星的时间 87 if (i == 0) 88 last = meteor[i].t; 89 else 90 last = max(last, meteor[i].t); 91 92 //更新地图上某个点的最快的流星下落时间 93 for (int j = 0; j < 5; j++) 94 { 95 int tx = meteor[i].x + go[j][0]; 96 int ty = meteor[i].y + go[j][1]; 97 98 if (tx >= 0 && ty >= 0 && map[tx][ty]>meteor[i].t) 99 { 100 map[tx][ty] = meteor[i].t; 101 } 102 } 103 } 104 105 if (map[0][0] == 0) //起始点被砸直接gg 106 printf("-1\n"); 107 else //否则bfs 108 printf("%d\n", bfs()); 109 } 110 return 0; 111 }
标签:
原文地址:http://www.cnblogs.com/iswoit/p/4446543.html