CSU-2112: Wells的明星生活

Description

和很多人想的不同,Wells其实是很低调的。

刚刚过了520和521,爱信不信,巨怂Wells和喜欢的小姐姐表白了!

Wells那是相当相当低调——之后的约会也是。不过,这次Wells遇到麻烦了……

Wells和小姐姐正在浪漫的约会呢,Wells猛然得到最新消息,有若干狗仔团队正闻讯蜂拥而来(Wells毕竟还是蛮很有名气的嘛)……

Wells真是不理解现在这些人对八卦的渴望怎么那么大,连保密工作做的这么好的Wells都未能幸免,这真是……

算了,别扯了,先溜吧,被狗仔队逮到可不好。

但是,Wells最近心情真的不好,厌睡厌食还厌学,难得和小姐姐的浪漫约会真不想撤,那么就能呆多久呆多久吧,Wells希望在不会被抓的前提下和小姐姐呆尽量久的时间。

城市可以看做是N行N列的方格,每一个格子会是一个建筑物,一片空地,一个狗仔队的窝点,或者是Wells的家。我们认为两个格子如果有相同的边,那么就是相邻的。城市里居民都是良民,每次走的时候,只会走相邻的格子。显然的,在私闯民宅可不好,所以不论是谁都不会闯到建筑物里的……

由于要保护小姐姐, Wells每一秒至多走S步,S可能很大,因为这是爱情的力量!

当Wells得知狗仔队将至的消息时,Wells在和小姐姐约会,而狗仔队都在各自窝点。随着时间的前进,每一秒都会按照如下的顺序发生着一些事件:

  • 如果Wells还在约会地点,那么他可以选择现在这一秒是和小姐姐浪漫,还是开始逃跑——如果是继续浪漫,那么这一秒Wells是不会移动的,如果逃跑,那么接下来Wells可以在城市里移动不超过S步——当然的,开始逃跑了怎么还会有心思浪漫呢?所以一旦离开了,Wells就会保护着小姐姐一直不停的逃跑。当然了,如果在某个位置遇到了狗仔队,那么可怜的Wells就要悲剧了…

  • 当Wells决定或者移动完毕之后,所有的狗仔队会向四周更远的格子移动一步——当然,也只会走到空地上,并且最邪恶的是一旦狗仔队走到了一个格子,就会派一个狗仔留守在那里——或者可以这么说,如果格子a和b是相邻的空地,并且在前一秒狗仔队占据了格子a,那么这一秒过后,a和b都将被狗仔队占据。最开始的时候,狗仔队占据了所有狗仔窝点所在的格子。

狗仔和Wells都不能走出城市。并且,显然的,根据规则,Wells继续和小姐姐浪漫的时间,必然是一个整数秒。

狗仔队是无法占领Wells的家的,所以Wells只要回到家里就安全啦!

现在Wells想知道如果要能够安全带着小姐姐回到家,那么最多他还能和小姐姐浪漫多长时间呢?

Input

第一行两个整数,N,S ,1≤N≤800 1≤S≤1000

接下来N行每行N个字符描述每个格子的具体情况

T 这个格子是一个建筑物

G 这是一块空地

M 这是Wells和小姐姐浪漫的地方,当然也是个空地

D 这是Wells的家

H 这是一个狗仔队的窝点

Output

一行一个整数,表示Wells最多还能和小姐姐浪漫多长时间,如果Wells不可能回到家了,那么就输出-1,否则显然答案是非负整数。

约定:

地图中有且仅有一个M,一个D,并且至少有一个H。

同样的,保证一定存在一条路能够从M走到D(否则Wells是怎么去和小姐姐约会的呢?)

保证答案不为无限大

Sample Input

7 3 
TTTTTTT 
TGGGGGT 
TGGGGGT 
MGGGGGD 
TGGGGGT 
TGGGGGT 
TGHHGGT 

Sample Output

2 

这题思路是利用了二分和bfs来做的,首先我们读题意知道狗仔每一秒都向四周在扩赛,而well则可以一次跨越多个格子,所以我们先预处理一下,init()函数来算出狗仔到达每一个格子所需要花费的时间,记录在t[maxn][maxn]数组里面,然后来利用bfs,well达到的实际未知,我们可以利用二分的思想,每次猜一个time,然后利用bfs检验是否可以到达。然后就是bfs里面的东西了,因为well最多一秒走多步,所以给两个变量,一个记录步数,一个记录时间,就是step,与wellt,当到达临界值k的时候wellt才会在之前的基础上加1,二分得到的答案,在最后还是需要得到检验的,因为如果一直不行,到最后也会跳出二分,所以在最后再检验一下,输出所得到的值。

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <iomanip>
#include <queue>
using namespace std;

typedef long long LL;
const double eps=1e-8;
const int maxn=805;
char s[maxn][maxn];
int vis[maxn][maxn],t[maxn][maxn];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,k;
int sx,sy,ex,ey;
struct Node
{
    int x,y;
    int step,wellt;
    int papt;
};
Node wellnow,papnow;
queue<Node>q;

void init()
{
    Node temp,next;
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        t[temp.x][temp.y]=temp.papt;
        for(int i=0;i<4;i++)
        {
            next.x=temp.x+dx[i];
            next.y=temp.y+dy[i];
            if(s[next.x][next.y]=='G'&&!vis[next.x][next.y])
            {
                next.papt=temp.papt+1;
                vis[next.x][next.y]=1;
                q.push(next);
            }
        }
    }
}

int bfs(int mid)
{
    memset(vis,0,sizeof(vis));
    while(!q.empty())
        q.pop();
    Node temp,next;
    wellnow.x=sx;wellnow.y=sy;
    wellnow.step=wellnow.wellt=0;
    q.push(wellnow);
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            next.x=temp.x+dx[i];
            next.y=temp.y+dy[i];
            next.step=temp.step+1;
            next.wellt=temp.wellt;
            if(next.step==k)
            {
                next.step=0;
                next.wellt=temp.wellt+1;
            }
            if(s[next.x][next.y]=='G'&&!vis[next.x][next.y]&&(mid+next.wellt)<t[next.x][next.y])
            {
                vis[next.x][next.y]=1;
                q.push(next);
            }
            else if(s[next.x][next.y]=='D')
                return 1;
        }
    }
    return 0;
}

int main()
{
	cin>>n>>k;
	memset(vis,0,sizeof(vis));
	memset(t,0,sizeof(t));
	memset(s,'T',sizeof(s));
	for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>s[i][j];
            if(s[i][j]=='H')
            {
                papnow.x=i;papnow.y=j;
                papnow.papt=0;
                vis[i][j]=1;
                q.push(papnow);
            }
            else if(s[i][j]=='M')
            {
                sx=i;sy=j;
            }
            else if(s[i][j]=='D')
            {
                ex=i;ey=j;
            }
        }
    }
    init();
    int leftt=1,rightt=n*n,mid;
    while(leftt<=rightt)
    {
        mid=(leftt+rightt)/2;
        if(bfs(mid))
            leftt=mid+1;
        else
            rightt=mid-1;
    }
    int ans=bfs(rightt);
    if(ans==0)
        cout<<"-1"<<endl;
    else
        cout<<rightt<<endl;
	return 0;
}

/**********************************************************************
	Problem: 2112
	User: jk1601zr
	Language: C++
	Result: AC
	Time:348 ms
	Memory:8376 kb
**********************************************************************/

猜你喜欢

转载自blog.csdn.net/Abandoninged/article/details/81188572