Meteor Shower(3669)

大致题意:有一些东西会在指定的时间袭击某个点。,这个点的周围四个点也会被波及,现在有个人在(0,0)位置, 想要走到安全位置,只在第一象限, 问要走多少步, 如果不可以就输出-1.

方法:先处理出点会在什么时候不安全,然后用bfs求最短的步数。

注意:有可能会在0的时候就不安全。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int n, cont[400][400];
int d[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
bool vis[400][400];
struct node{
    int a, b, c;
}pp[50100];
bool cmp(node mm, node tt){
    return mm.c < tt.c;
}
struct pos{
    int x, y, time;
    pos(){}
    pos(int xx, int yy, int tt): x(xx), y(yy), time(tt){}
};
queue<pos>que;
int main(){
    int i, j;
    while(scanf("%d", &n) != EOF){
        memset(cont, -1, sizeof(cont));
        memset(vis, 0, sizeof(vis));
        while(!que.empty()){
            que.pop();
        }
        for(i = 1; i <= n; i++){
            scanf("%d%d%d", &pp[i].a, &pp[i].b, &pp[i].c);
        }
        sort(pp+1, pp+1+n, cmp);
        for(i = 1; i <= n; i++){
            node nd = pp[i];
            if(cont[nd.a][nd.b] == -1)
                cont[nd.a][nd.b] = nd.c;
            for(j = 0; j < 4; j++){
                int xx = nd.a + d[j][0];
                int yy = nd.b + d[j][1];
                if(xx<0 || yy < 0)  continue;
                if(cont[xx][yy] == -1)
                    cont[xx][yy] = nd.c;
            }
        }
        que.push(pos(0,0,0));
        vis[0][0] = 1;
        int flag = 0;
        pos temp;
        while(!que.empty()){
            temp = que.front();
            if(cont[temp.x][temp.y] == -1){
                flag = 1;
                break;
            }
            que.pop();
            for(i = 0; i < 4; i++){
                int xx = temp.x + d[i][0];
                int yy = temp.y + d[i][1];
                if(xx<0 || yy<0)  continue;
                if(vis[xx][yy] == 1)   continue;
                if(temp.time+1 >= cont[xx][yy] && cont[xx][yy]!=-1)  continue;
                que.push(pos(xx, yy, temp.time+1));
                vis[xx][yy] = 1;
            }
        }
        if(flag == 1)
            printf("%d\n", temp.time);
        else
            printf("-1\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值