UVALive-7297-Hounded by Indecision

题目链接:https://vjudge.net/problem/UVALive-7297

OK, maybe stealing the Duchess’s favorite ruby necklace was not such a good idea. You were making your way toward the city gates when you heard the sound you had been dreading: a sharp whistle followed by an answering bark. You know that the constable has just fetched his favorite hound and is starting to search for you. They might head straight for a gate. They might try to pick up your trail on the way. You really can’t guess. But if they reach the gate before you, you’re caught. If they happen
across your trail, the hound will pick up your scent. The dog knows your scent already — this isn’t your first offense! The constable will loose the hound, who can run fast once he has the trail to follow.
        You have a dilemma. If you are absolutely sure that you can reach the gates before the guard and before being overtaken by the hound, you can keep the necklace. But if you aren’t sure, you need to drop the necklace right now into the nearest pile of rubbish and saunter casually away. Even if they grab you, without the necklace in your hands they will eventually release you.
        So, keep the necklace or drop the necklace?
        The town is modeled as a rectangular maze of discrete squares. It is surrounded by a wall that contains one or more exits. You know, of course, your own position within the town. You also know the location of the kennel where the constable and the hound start out.
1. In each turn (unit of time), you, the constable, and the hound move simultaneously.
2. You can move zero or one square(s) horizontally or vertically per turn.
3. Initially, the constable and hound move together, also zero or one square(s) vertically or horizon-tally per turn.
4. If the constable and the hound, moving together, reach a square that you have previously occupied,the hound catches your scent, and the constable looses the hound. On each subsequent turn, the hound follows your trail at a speed of 1 or 2 square(s) per turn.
5. If the constable and/or the hound overtake you (occupy the same square as you), you are caught. To escape, you must reach an exit at least one turn before the constable and/or hound.
Input
Input consists of one or more mazes. Each maze begins with a line containing two integers, W and H,denoting the width and the height of the maze. End of input is indicated when either of these valuesis less than 3. Neither dimension is greater than 50.
This is followed by H lines of input, each containing W characters.The interpretation of the characters in these lines is as follows:
1. The space character ( ) denotes an open space.
2. ‘K’ is an open space denoting the kennel which is the starting position of the constable and the hound. There will be exactly one of these in any maze.
3. ‘T’ is an open space denoting the original position of the thief (you). There will be exactly one of these in any maze.
4. ‘X’ denotes a wall.

5. ‘E’ is an open space representing an exit (city gate). All exits will occur on the outer perimeter (as defined by the W and H values) of the maze.All mazes will be completely enclosed by a combination of ‘X’ and ‘E’ characters. There is at least one path between the kennel and you, and there is at least one path between you and each exit.
Output
         For each maze, print a single line of output. If there is a path that you can take that will guarantee that you can escape, no matter what path what the constable and hound take, then print ‘KEEP IT’. If there is no path that offers such a guarantee, print ‘DROP IT’.
Notes about the sample below:
          In the first case, the constable and his hound can discover, on turn 7, the space where the thief had stood on turn 4. The hound is loosed and overtakes the thief on turn 10 (or earlier if the thief doubles back). In the second case, the thief can reach the city gate in 13 turns, at which point the constable and hound hit his trail. However, the thief is still able to get out of the city before the hound catches him.

Sample Input

19 11
XXXXXXXXXXXXXXXXXXX
X                 X
E                 X
X   XXX XXX  K    X
X   X     X       X
X   X     X       X
X   X  T  X       X
X   X     X       X
X   XXXXXXX       X
X                 X
XXXXXXXXXXXXXXEXXXX

 

19 11
XXXXXXXXXXXXXXXXXXX
X                 X
E                 X
X   XXX XXX  K    X
X   X     X       X
X   X     X       X
X   X  T  X       X
X         X       X
X   XXXXXXX       X
X                 X
XXXXXXXXXXXXXXEXXXX
0 0

Sample Output
DROP IT
KEEP IT

 

 

#include <iostream>
#include <algorithm>
using namespace std;
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#define mem(a) memset(a,0,sizeof(a))
#define maxn 100
int m,n;
char a[maxn][maxn];
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int vis[maxn][maxn];
int police[maxn][maxn];   //警察到达该点所需的最小步数
int thief[maxn][maxn];   //小偷在该点还可以走的步数
struct A
{
    int x,y;
    int step;
    int lestep;
};
void ceshi();
bool cc(int i,int j)
{
    if(i>=0&&i<n&&j>=0&&j<m)
           if(a[i][j]!='X')
        return 1;
    return 0;
}
void pol_time_BFS(int x,int y)  //初始化police数组
{
    queue<A> q;
    vis[x][y]=1;
    A now;
    now.x=x;
    now.y=y;
    now.step=0;
    police[x][y]=0;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            A t;
            t.x=now.x+dir[i][0];
            t.y=now.y+dir[i][1];
            t.step=now.step+1;
            if(cc(t.x,t.y)&&police[t.x][t.y]==-1)
            {
                q.push(t);
                police[t.x][t.y]=t.step;
            }
        }
    }
    return;
}
bool thief_BFS(int x,int y)
{
    A now;
    now.x=x;
    now.y=y;
    now.step=0;
    now.lestep=2*police[x][y];
    thief[x][y]=2*police[x][y];
    queue<A> q;
    q.push(now);
    while(!q.empty())   //改进广搜,除去墙和网格外的不能走外,小偷于警察达到的时间关系不满足的话,
    {                   //也不能入队列
        A t;
        now=q.front();
        q.pop();
        if(a[now.x][now.y]=='E')
            return 1;
        for(int i=0;i<4;i++)
        {
            t.x=now.x+dir[i][0];
            t.y=now.y+dir[i][1];
            t.step=now.step+1;

            if(!cc(t.x,t.y))
                continue;
            if(t.step>=police[t.x][t.y])  //如果小偷到达该点所需的时间大于警察
                continue;                 //到达该点的时间,则不入队列

            t.lestep=min(now.lestep-1,2*(police[t.x][t.y]-t.step));
            //now.lestep-1 ,即上一个点的剩余步数为now.lestep,走到该点时为now.lestep-1
            //2*police[t.x][t.y]-2*t.step  ,警察到达该点的时间大于小偷到达该点的时间,
            //所以police[t.x][t.y]-t.step 为小偷领先警察到达该点的时间,然后因为警察到达后
            //狗会以二倍的速度去追小偷,所以小偷还能再跑的时间为2*(police[t.x][t.y]-t.step)
            //因为要保证在最坏的情况下警察都抓不到小偷,所以,要取最小值
            if(t.lestep<=thief[t.x][t.y])
                continue;
            //thief数组里面已经存的是小偷还能走的最多的步数,所以如果得到的剩余步数小于
            //thief[t.x][t.y]时,这样的话小偷就不能够走到出口,不会入队列
            thief[t.x][t.y]=t.lestep;
            q.push(t);
        }
    }
    return 0;
}

int main()
{
    while(cin>>m>>n)
    {
        if(m==0&&n==0)
            break;
        getchar();
        for(int i=0;i<n;i++)
            gets(a[i]);
        memset(police,-1,sizeof(police));
        mem(thief);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(a[i][j]=='K')
                    pol_time_BFS(i,j);
        int ans;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(a[i][j]=='T')
                    ans=thief_BFS(i,j);
        if(ans)
            cout<<"KEEP IT"<<endl;
        else
            cout<<"DROP IT"<<endl;
        //ceshi();
    }
    return 0;
}
void ceshi()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            cout<<a[i][j];
        cout<<endl;
    }
    cout<<endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            printf("%2d ",police[i][j]);
        cout<<endl;
    }
    cout<<endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            printf("%2d ",thief[i][j]);
        cout<<endl;
    }
    cout<<endl;
    return ;
}

以下摘自:https://blog.csdn.net/xbb224007/article/details/77810124

题目大意:
给你一个N*M的矩阵,里面有一个小偷,一个警察和一条警犬以及若干个出口,警察在追捕小偷。每次小偷和警察只能在水平或者竖直方向上移动一格,小偷和警察同时移动。起初警察和警犬在一起追捕,当警察到达小偷到达过的地点时,警犬则会以2倍的速度追赶小偷,而警察速度不变。问小偷能不能一定有办法在被追到之前离开矩阵。
解题思路:
题目就是让你搜索出口,并且看是否有方案满足不被警察追到。
其实我们只要解决如何判断某一个点能不能走,如果这个解决了,那么就依次判断下去就可以了,最后看是否可以到达出口。(记为A点)
一:收先可以判断的是小偷必须在警察之前到达A点(要保证一定不被抓),计小偷到A的时间为T1,警察到A点的时间为T2,则T2>T1;
二:满足条件一后,当小偷到达A点以后,由于当警察到达A点之后,警犬会以两倍的速度追赶,所以之后小偷又一个最大的移动时间。即超过该时间会被警犬追上。
计算该时间:当警察到达A点时(距离小偷离开A点已经有T2-T1的时间了),小偷领先警察T2-T1,之后警犬以小偷2倍的速度追赶,可以知道警犬会花费T2-T1的时间追上小偷。所以小偷到达A点以后最大的移动时间为Limit_Time=2*(T2-T1);
三:假设小偷在前一个点剩余的最大移动时间为T,那么在A点小偷的最大剩余移动时间为T-1,那么要保证不被警察抓到,在A点的剩余时间就应该取条件二与T-1的较小值,即Limit_Time=min(T-1,Limit_Time),然后每搜到一个点记录在该点的最大剩余时间。当重复搜到某个点时,如果后者可以使最大剩余时间变大(说明有更优的方案到达该点),则入队,并更新当前点最多剩余时间,否则不入队。
四:判断搜索。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值