码迷,mamicode.com
首页 > 其他好文 > 详细

【单向BFS】Escape HDU - 3533

时间:2020-07-24 21:45:27      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:距离   end   cap   无法   sync   code   ble   std   pop   

Escape HDU - 3533

题意:

小A要从\((0,0)\)逃到\((n,m)\),他的精力值为\(d\),每秒可以向东南西北四个方向走一格,或保持原地不动。但无论他是否移动,精力值每秒都会损失1点。路上他会遇到炮塔射击。给定\(k\)座炮塔的射击方向、射击间隔、子弹速度、坐标。第0秒小A开始逃跑,且所有炮塔开始射击。当小A被子弹击中或精力值耗尽,即失败。问小A能否抵达终点,若能,输出最小步数。

注意:

1.当小A与子弹在同一格,且该格是子弹的终点时,才算是被击中;如果子弹仅是经过了小A所在格子,不算被击中。

2.炮塔所在位置不能走。

3.炮塔会挡住射向它的子弹,但不会被摧毁。

4.子弹与子弹之间互不影响。

思路:

以人为对象进行BFS。判断条件即走到新格子时是否会恰好遇到子弹。根据题意,只需要判断新格子向四个方向延伸后分别所遇到的第一座炮塔即可。

子弹的判定有点复杂,详见注释,其他没啥难点。

int n, m, k, d;

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

struct Castle {
    char dir;
    int t;
    int v;
    bool castle;
}Map[105][105];

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

bool vis[105][105][105];
//vis[x][y][time]
//time时刻的格子(x,y)只能访问一次

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

    while (!q.empty()) {
        node temp = q.front();
        q.pop();
        if (temp.step > d) return 0;
        if (temp.x == n && temp.y == m) return temp.step;

        for (int i = 0; i < 5; i++) {
            int nx = temp.x + dx[i];
            int ny = temp.y + dy[i];
            int nstep = temp.step + 1;
            if (nx<0 || ny<0 || nx>n || ny>m) continue;
            if (Map[nx][ny].castle) continue;
            if (vis[nx][ny][nstep]) continue;

            int safe = 1;

            //判断新格子是否会被射击
            int N = nx, S = nx, W = ny, E = ny;
            for(int N=nx-1;N>=0;N--) {
                if (N < 0) break;
                if (Map[N][ny].castle) {
                    if (Map[N][ny].dir != ‘S‘) break;
                    int dis = N - nx;
                    //人与炮台的距离
                    if (dis % Map[N][ny].v != 0) break;
                    //如果不能整除速度,则子弹无法恰好抵达这个位置,安全
                    int timee = nstep - dis / Map[N][ny].v;
                    //能恰好抵达这个位置的子弹是在第timee秒射出的
                    if (timee < 0) break;
                    //是负数,不可能射出,安全
                    if (timee % Map[N][ny].t != 0) break;
                    //不是周期时间点,不可能射出,安全
                    safe = 0;
                    break;
                }
            }
            if (!safe) continue;

            for(int S=nx+1;S<=n;S++){
                if (S > n) break;
                if (Map[S][ny].castle) {
                    if (Map[S][ny].dir != ‘N‘) break;
                    int dis = S - nx;
                    if (dis % Map[S][ny].v != 0) break;
                    int timee = nstep - dis / Map[S][ny].v;
                    if (timee < 0) break;
                    if (timee % Map[S][ny].t != 0) break;
                    safe = 0;
                    break;
                }
            }
            if (!safe) continue;

            for(int W=ny-1;W>=0;W--) {
                if (W < 0) break;
                if (Map[nx][W].castle) {
                    if (Map[nx][W].dir != ‘E‘) break;
                    int dis = ny - W;
                    if (dis % Map[nx][W].v != 0) break;
                    int timee = nstep - dis / Map[nx][W].v;
                    if (timee < 0) break;
                    if (timee % Map[nx][W].t != 0) break;
                    safe = 0;
                    break;
                }
            }
            if (!safe) continue;

            for(int E=ny+1;E<=m;E++) {
                if (E > m) break;
                if (Map[nx][E].castle) {
                    if (Map[nx][E].dir != ‘W‘) break;
                    int dis = E - ny;
                    if (dis % Map[nx][E].v != 0) break;
                    int timee = nstep - dis / Map[nx][E].v;
                    if (timee < 0) break;
                    if (timee % Map[nx][E].t != 0) break;
                    safe = 0;
                    break;
                }
            }
            if (!safe) continue;

            node now;
            now.step = nstep;
            now.x = nx;
            now.y = ny;
            q.push(now);
            vis[nx][ny][nstep] = true;

        }
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    //int t; cin >> t; while (t--) {
    while(cin>>n>>m>>k>>d){

        memset(Map, 0, sizeof(Map));
        memset(vis, false, sizeof(vis));
        for (int i = 1; i <= k; i++) {
            char ch;
            int t, v, x, y;
            cin >> ch >> t >> v >> x >> y;
            Map[x][y].dir = ch;
            Map[x][y].t = t;
            Map[x][y].v = v;
            Map[x][y].castle = true;
        }

        int ans = bfs();
        if (!ans) cout << "Bad luck!" << endl;
        else cout << ans << endl;

    }
    return 0;
}

【单向BFS】Escape HDU - 3533

标签:距离   end   cap   无法   sync   code   ble   std   pop   

原文地址:https://www.cnblogs.com/streamazure/p/13374167.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!