HDU3533 Escape(预处理+bfs)

HDU 3533

题意:给定一个网格(n + 1 行,m + 1列,0~n,0~m),小明站在(0, 0)点,要到达(n, m)点,现在在一些网格处安置了炮台,炮台向固定的方向(NSWE)并且每隔一段时间发射炮弹,小明初始时有一定的HP,小明可以做以下5种操作:

  1. 向N、S、W、E移动一格
  2. 站着不动

每一种操作都会耗费1点HP,并且在移动的之后不能被炮弹打中,问小明能活着否到达(n, m)点

题目中说为了简化问题,注意:

  1. 小明只会1秒1秒的移动,要么就不动(可以停住几秒来躲避炮弹)
  2. 只有小明和炮弹同时到达某一格的时候小明才会被击中(就是小明不会再非整数秒被击中)
  3. 炮弹之间不会相互影响
  4. 如果一个炮弹A击中了炮台(不管是否是整数秒),那么炮台就会把他挡住,A就无法再向前走了
  5. 炮弹发射时间的问题,比如一个炮台在(1, 1)位置,他每隔1s向N方向发射一个炮弹,炮弹的速度为 一格/s,那么过程是这样的:在1s的时候,炮台发射炮弹,此时炮弹在(1, 1),然后再过1s,炮弹到达(0,1),其他的类似。

思路:这题,一开始用的是bfs+模拟,RE了,正确思路是预处理+bfs,题目数据中说小明的HP为(dle1000),所以小明在网格中呆的时间不会超过1000,所以可以根据所有的炮台和他们发射的方向搞一张表f,其中f[a][b][c]表示网格中(a, b)处在c时刻是否有炮弹袭击,然后bfs就行了

这题我最想骂娘的地方是我把构造函数删掉改成参数列表赋值后,没改参数顺序,结果卡了我一下午,一下午的宝贵时光啊!!!

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>

using namespace std;

const int N = 110, D = 1010;

int dx[] = {-1, 1, 0, 0, 0}, dy[] = {0, 0, -1, 1, 0};


bool hit[N][N][D];
int st[N][N];
int m, n, k, d;

struct castle{
  int o; // 方向
  int x, y; // 位置
  int v; // 速度
  int t; // 间隔
}ca[N];

struct node{
    int x, y;
    int t;
};

int bfs(){
    queue<node> q;
    q.push({0, 0, 0});
    st[0][0] = 1;

    while(q.size()){
        node h = q.front();
        q.pop();
        
        if(h.t >= d) continue;
        
        for(int i = 0; i < 5; i ++){
            int x = h.x + dx[i], y = h.y + dy[i];
            if(x < 0 || y < 0 || x > n || y > m) continue;
            if(hit[x][y][h.t + 1]) continue;
            if(st[x][y] && (x != h.x || y != h.y)) continue;
            
            st[x][y] = 1;
            q.push({x, y, h.t + 1});

            if(x == n && y == m) return h.t + 1;
        }
    }
    
    return -1;
}

int main(){
    while(cin >> n >> m >> k >> d){
        memset(st, 0, sizeof st);
        memset(hit, 0, sizeof hit);
        
        for(int i = 0; i < k; i ++){
            char c;
            int o, t, v, x, y;
            cin >> c >> t >> v >> x >> y;
            if(c == 'N') o = 0;
            if(c == 'S') o = 1;
            if(c == 'W') o = 2;
            if(c == 'E') o = 3;
            st[x][y] = 1;
            ca[i] = {o, x, y, v, t}; // FUCK-UP
        }
        
        for(int i = 0; i < k; i ++){
            for(int j = 1; j <= d; j ++){
                if(j % ca[i].t == 0){
                    int x = ca[i].x, y = ca[i].y;
                    int o = ca[i].o;
                    int u = 0, v = 0;
                    while(u <= ca[i].t){
                        v ++;
                        x += dx[o], y += dy[o];
                        if(x < 0 || y < 0 || x > n || y > m) break;
                        if(st[x][y]) break;
                        if(v % ca[i].v == 0){
                            u ++;
                            hit[x][y][j + u] = 1;
                        }
                    }
                }
            }
        }
        
        int res = bfs();
        if(~res) cout << res << endl;
        else cout << "Bad luck!" << endl;
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/tomori/p/15349625.html