POJ 3669 Meteor Shower

题目链接:

http://poj.org/problem?id=3669

解题思路:

给m个坐标,分别会在不同的t时刻下流星雨,请求出最少需要多长时间才能到达安全的地方,被流星雨摧毁的地方不能再走了。。。

首先预处理,将流星出现的最早时间用vis数组标记,然后再用bfs搜索。。。注意数组要开到400多,不然会wrong。。。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

struct node{
    int x,y,t;
};
const int dx[] = {0,-1,0,1,0},dy[] = {0,0,-1,0,1};
int vis[410][410];//嚓,题目数据有问题,开400才能过


bool check(int x,int y){
    if(x<0 || x > 400 || y <0 || y > 400)
        return false;
    return true;
}

int bfs(){
    if(vis[0][0] == 0)
        return -1;
    else if(vis[0][0] == -1)
        return 0;
    node cur;
    cur.x = 0;cur.y = 0;cur.t = 0;
    queue<node> q;
    q.push(cur);
    while(!q.empty()){
        cur = q.front();
        q.pop();
        //printf("%d %d %d\n",cur.x,cur.y,cur.t);
        node tmp;
        for(int i = 1; i <= 4; i++){
            tmp.x = cur.x+dx[i];tmp.y = cur.y+dy[i];tmp.t = cur.t+1;
            if(!check(tmp.x,tmp.y))
                continue;
            if(vis[tmp.x][tmp.y] == -1)
                return tmp.t;
            if(vis[tmp.x][tmp.y] > cur.t+1){
                vis[tmp.x][tmp.y] = tmp.t;//走过要记为标记
                q.push(tmp);
            }
        }
    }
    return -1;
}

int main(){
    int m;
    while(~scanf("%d",&m)){
        int x,y,t;
        memset(vis,-1,sizeof(vis));
        for(int i = 0; i < m; i++){
            scanf("%d%d%d",&x,&y,&t);
            for(int j = 0; j < 5; j++){
                int xx = x+dx[j],yy = y+dy[j];
                if(check(xx,yy)){
                    if(vis[xx][yy] == -1)
                        vis[xx][yy] = t;
                    else
                        vis[xx][yy] = min(vis[xx][yy],t);
                }
            }
        }
        printf("%d\n",bfs());
    }
    return 0;
}


你可能感兴趣的:(搜索)