UVALive 7297 Hounded by Indecision BFS

题目链接:Hounded by Indecision

题意:map中给出小偷的位置,警察的位置。警察有一只狗,开始的时候警察和狗一起行动,也就是看做一个格子,当警察遇见小偷走过的格子时,狗就会嗅到它的气味,以2倍的速度追捕小偷。现在,小偷希望知道自己是否有安全路线逃出去,以此决定是否要继续拿着偷的东西。出口不止一处,只有一个警察和一只狗,一个小偷。【知道也才不告诉他,哼。】

思路:因为小偷每走到一个格子时,时间为t1,决定他是否被抓到的因素是警察到这里的时间t2。当t1>=t2时,小偷被抓,当t1<t2时,小偷还能从该点继续走,直到t2-t1+t2时刻被狗抓住或者跑出去。所以首先对警察bfs,确定警察到map上的每个格子最短时间t2。然后,对小偷bfs,判断当前点是否能走的条件:map范围内且不是围墙 && 到达时间t1<t2 && 还没有到限制的时间 && (没有走过 || 之前走到当前路线的时间比现在小)。注意:我们每到一个新的点,当前点的限制是前一个点的限制和当前点计算得到的限制的max值,而我们可以选择一条路线使得再次到达当前点的步数更小,获得的逃跑时间更长。

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#define maxn 210
#define inf 0x7f7f7f7f
using namespace std;

int step[maxn][maxn];
char mp[maxn][maxn];
int vis[maxn][maxn]; // lim
int dir[4][2] = {1,0, -1,0, 0,1, 0,-1};
int w, h;

struct Node {
    int x, y, lim, step;
    Node () {
        lim = inf;
        step = inf;
    }
}q[maxn*maxn*maxn], st;

struct Point{
    int x, y;
}que[maxn*maxn*maxn], now, nxt, temp;

bool check(int x, int y) {
    if (x>=0 && x<h && y>=0 && y<w && mp[x][y] != ‘X‘)
        return true;
    return false;
}

void bfs_police(int px, int py){
    memset(vis, 0, sizeof(vis));
    vis[px][py] = 1;
    step[px][py] = 0;
    now.x = px, now.y = py;
    int head = 0, tail = -1;
    que[++tail] = now;
    while(head <= tail) {
        now = que[head++];
        for (int i=0; i<4; ++i) {
            nxt.x = now.x + dir[i][0];
            nxt.y = now.y + dir[i][1];
            if (check(nxt.x, nxt.y) && vis[nxt.x][nxt.y] == 0) {
                step[nxt.x][nxt.y] = step[now.x][now.y] + 1;
                vis[nxt.x][nxt.y] = 1;
                que[++tail] = nxt;
            }
        }
    }
}

bool bfs_thief(Node st) {
    memset(vis, 0, sizeof(vis));
    st.step = 0;
    st.lim = (step[st.x][st.y] - st.step) + step[st.x][st.y];
    int head = 0, tail = -1;
    q[++tail] = st;
    vis[st.x][st.y] = st.lim;

    while(head <= tail) {
        Node now = q[head++];
        if (mp[now.x][now.y] == ‘E‘) {
            return true;
        }
        for (int i=0; i<4; ++i) {
            Node nxt = now;
            nxt.x += dir[i][0];
            nxt.y += dir[i][1];
            nxt.step++;
            if (check(nxt.x, nxt.y)) {
                int lim = step[nxt.x][nxt.y] + (step[nxt.x][nxt.y] - nxt.step);
                if (lim < nxt.lim) nxt.lim = lim;
                if (nxt.step < step[nxt.x][nxt.y] && nxt.step < nxt.lim && (vis[nxt.x][nxt.y] == 0 || nxt.lim > vis[nxt.x][nxt.y])) {
                    vis[nxt.x][nxt.y] = nxt.lim;
                    q[++tail] = nxt;
                }
            }
        }
    }
    return false;
}

int main() {
    //freopen("in.cpp", "r", stdin);
    while(~scanf("%d%d", &w, &h)) {
        if (w<3 || h<3) break;
        getchar();
        int px, py;
        for (int i=0; i<h; ++i) {
            gets(mp[i]);
            int len = strlen(mp[i]);
            for (int j=0; j<len; ++j) {
                if (mp[i][j] == ‘K‘) {
                    px = i, py = j;
                }
                else if (mp[i][j] == ‘T‘) {
                    st.x = i, st.y = j;
                }
            }
        }
        bfs_police(px, py);
        bool esc = bfs_thief(st);
        if (esc) printf("KEEP IT\n");
        else printf("DROP IT\n");
    }
    return 0;
}
时间: 2025-01-02 18:23:42

UVALive 7297 Hounded by Indecision BFS的相关文章

UVALive 6665 Dragon&#226;??s Cruller --BFS,类八数码问题

题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue&g

UVALive 7297 bfs

题意 一个小偷偷到了项链 他想知道自己是否可以逃出去 地图中有一个小偷 一个警察 警察有一条狗 一开始 小偷和警察的移动速度都是1 当警察走到小偷经过过的地方时 警察会有一条狗嗅到小偷的气味并且以2的速度去追 由于问题问的是 小偷是否必定有方法逃出 所以我们可以看作 有无限个警察从一个点出发去抓小偷 每经过一个点 这个点上就会有一个警察站着 所以会有一个limit来记录警察到达这个点的最短的时间 我们可以想到 小偷到这个点的时间和警察到达这个点的时间的差 就是小偷到这个点之后可以行动的时间(如果

UVALive 6485 Electric Car Rally (BFS,优先队列)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4496 In an attempt to demonstrate the practicality of electric cars, ElecCarCo is sponsoring a cross-country road rally. There are n chargin

UVALive 2520 Holedox Moving(BFS+状态压缩)

这个题目在比赛的时候我们是没有做出来的,但是听到他们说进制哈希的时候,感觉真的是挺高端的,于是赛后开始补题,本着我的习惯在看题解之前自己再试着写一遍,我当时存储状态的方法是string + map,我用string将蛇的各个位置都存下来,用map记录这个状态有没有出现过,当时是过了题目中给的样例,我就开始担心STL会不会超时,后来发现想多了,这个方法WA了,至于为什么,我还没明白,或许是状态的处理错误.总之我自己也觉得这个状态有点不靠谱..于是开始换用题解的方式.发现所谓的进制哈希,其实就是状态

UVALive 2035 The Monocycle(BFS状态处理+优先队列)

这道题目真是非常坎坷啊,WA了很多次,但所有的思路都是奔着广搜去想的,一开始出现了比答案大的数据,才想到了应该是优先队列,再说加上也肯定不会错.一开始我读错了题意,以为旋转并且前行需要的时间跟其他一样,但是旋转的动作是需要额外计时的.我的第一种方法错误原因还没有找到,我在旋转以后就直接改动了位置,感觉没有什么本质区别,旋转了以后,肯定要走啊,我直接加上时间也没什么问题,我也把所能想到的测试用例都试过了,与AC代码完全一致,真是搞不懂,这要是CF就好了.于是,学习了别人的代码,改了改我原先的地方,

UVALive 6485 Electric Car Rally (BFS,PQ)

https://icpcarchive.ecs.baylor.edu/index.php? option=com_onlinejudge&Itemid=8&page=show_problem&problem=4496 In an attempt to demonstrate the practicality of electric cars, ElecCarCo is sponsoring a cross-country road rally. There are n chargi

UVALive 6663 Count the Regions 离散+bfs染色_(:зゝ∠)_

题目链接:点击打开链接 gg..== #include <cstdio> #include <cstring> #include<iostream> #include <queue> #include <set> #include <map> #include <algorithm> #include <string> using namespace std; #define ll long long #def

UVALive 5066 Fire Drill BFS+背包

H - Fire Drill Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 5066 Description Joko is taking part in a fire drill which is held by the Jakarta Fire Department to recruit new firemen. The drill i

UVALive - 6455 Stealing Harry Potter&#39;s Precious (bfs+dfs)

https://cn.vjudge.net/problem/UVALive-6455 题目大意:题目上给出一个地图,其中@是人在地图上的出发点,#是墙,' . '是路.然后给出几个点,这些点表示财宝的所在地.问人是否能够得到所有的宝藏,如果能够的话给出所有的宝藏的最短的路径. 解题思路:由于只有最多4个宝藏所在地,所以只要用bfs找出出发点和财宝所在地距离到达其他点的步数.因为最多只有4个宝藏,所以可以暴力找出出发点到所有宝藏的最短距离. 暴力代码: 1 #include<stdio.h> 2