这一题,简单的广搜的应用,只是题目的陷进比较多。
题目大概的意思是,一个人在Point(0,0)的位置,然后会有陨石坠落,陨石坠落的地方的上下左右中都会被砸毁,每一个陨石会在第T秒坠落。问你找到一个安全的地方的最短时间,否则输出-1.
下面是AC的代码,有详细的注释:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int MAX = 50005; //陨石最大数量 class data { public: int x, y, Time; }; data s[MAX]; //陨石坠落的位置和时间 int map[305][305], M; //map表示point(i, j)位置运算坠落的最早时间。 bool safe[305][305], vis[305][305]; //safe是安全的地方,则为true int xy[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};//四个方位 int bfs() { queue<data>que; data temp, te; temp.x = temp.y = temp.Time = 0; //开始位置0,0和时间为0; que.push(temp); vis[0][0] = true; //标记已经返问过 while(!que.empty()) { te = que.front(); que.pop(); for(int i = 0; i < 4; i++) //四个方位进行搜索 { int x = te.x + xy[i][0]; int y = te.y + xy[i][1]; int time = te.Time + 1; if(x >= 0 && y >= 0 && map[x][y] > time && !vis[x][y]) //没返问过的,陨石还没落下的位置可以走 { if(safe[x][y]) //如果找到安全地方,返回时间。 return time; vis[x][y] = true; //标记已经返问过 temp.x = x; temp.y = y; temp.Time = time; que.push(temp); //入队 } } } return -1; //不能找到安全地方 } int main() { // freopen("data.txt", "r", stdin); //这里忘记注释掉了,wr了一次,坑 int i, j, k; while(scanf("%d", &M) != EOF) { memset(safe, true, sizeof(safe)); //初始化safe memset(vis, false, sizeof(vis)); //初始化vis for(i = 0; i < 305; i++) //初始化map for(j = 0; j < 305; j++) map[i][j] = 10000000; for(i = 0; i < M; i++) { scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].Time); safe[s[i].x][s[i].y] = safe[s[i].x - 1][s[i].y] = safe[s[i].x][s[i].y - 1] = safe[s[i].x + 1][s[i].y] = safe[s[i].x][s[i].y + 1] = false; //标记陨石会砸到的地方 } data temp; for(j = 0; j < M; j++) //更新map中每一个位置陨石最早掉落的时间,注意,是最早的时间。 { //刚开始忘记考虑这一点了。坠落的时间不是降序 temp = s[j]; if(map[temp.x][temp.y] > temp.Time) map[temp.x][temp.y] = temp.Time; for(k = 0; k < 4; k++) { int x = temp.x + xy[k][0]; int y = temp.y + xy[k][1]; if(x >= 0 && y >= 0 && map[x][y] > temp.Time) map[x][y] = temp.Time; } } if(map[0][0] == 0) //开始时,陨石就砸下来了,就直接死掉了,-1; printf("-1\n"); else printf("%d\n", bfs()); } return 0; }
时间: 2024-10-12 02:03:43