CSU-2112 Wells的明星生活 预处理&BFS&二分

为涛爷约会女朋友加油!\(` o ')/

题目非常长了:

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是怎么去和小姐姐约会的呢?)

保证答案不为无限大

分析:

肥肠复杂乍一看,同时移动wells和狗仔是不可能实现的,所以想到预处理狗仔到达各空地的最早时间;wells回到家的过程应该是用BFS,至于步数,自然是单位时间内越大越好,1s走s步,就继续标记各空地,用两个变量,一个记录s以内的步数,一个记录时间(后来又想,第二个变量也可以不用,直接判断该步数是过去了多少时间的就可以),判断满足约会时间t+走到空地的时间tt<狗仔最早到达此处的时间(预处理的标记);约会时间这个不确定的话,就只好选择二分约会时间咯。

代码很长也:

//二分&&狗仔预处理&&BFS
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int maxn=800;
const int maxs=1000;
const int inf=99999;

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

int n,s;
char c[maxn+10][maxn+10];
int w[maxn+10][maxn+10],vst[maxn+10][maxn+10];
int sx,sy,ex,ey;
struct step{
    int x,y;
    int et,tt;
};
queue <step> q;

void prework()
{
    step now,tem;
    int i;

    while(!q.empty()){
        now=q.front();
        q.pop();
        w[now.x][now.y]=now.et;
        for(i=0;i<4;++i){
            tem.x=now.x+dx[i];
            tem.y=now.y+dy[i];
            if(c[tem.x][tem.y]=='G'&&!vst[tem.x][tem.y]){
                tem.et=now.et+1;
                vst[tem.x][tem.y]=1;
                q.push(tem);
            }
        }
    }
}

bool gohome(int t)
{
    int i,tt;
    step now,tem;

    memset(vst,0,sizeof(vst));
    while(!q.empty()) q.pop();
    now.x=sx;now.y=sy;
    now.et=now.tt=0;
    q.push(now);
    while(!q.empty()){
        now=q.front();
        q.pop();
        for(i=0;i<4;++i){
            tem.x=now.x+dx[i];
            tem.y=now.y+dy[i];
            tem.et=now.et+1;
            tem.tt=now.tt;
            if(tem.et==s){
                tem.et=0;
                tem.tt=now.tt+1;
            }
            if(c[tem.x][tem.y]=='G'&&!vst[tem.x][tem.y]&&(t+tem.tt)<w[tem.x][tem.y]){
                vst[tem.x][tem.y]=1;
                q.push(tem);
            }
            else if(c[tem.x][tem.y]=='D'){
                return true;
            }
        }
    }

    return false;
}

void binary()
{
    int left=0,right=maxn*maxn,mid;

    if(!gohome(left)){
        printf("-1\n");
        return;
    }
    while(left<=right){
        mid=(left+right)/2;
        if(gohome(mid)){
            left=mid+1;//printf("mid:%d r:%d\n",mid,right);
        }
        else{
            right=mid-1;
        }
    }
    printf("%d\n",right);
}

int main()
{
    int i,j;
    step tems;

    scanf("%d%d",&n,&s);
    memset(vst,0,sizeof(vst));
    for(i=0;i<=n+1;++i){
        c[0][i]=c[i][0]=c[n+1][i]=c[i][n+1]='T';
    }
    for(i=1;i<=n;++i){
        for(j=1;j<=n;++j){
            scanf(" %c",&c[i][j]);
            w[i][j]=inf;
            switch(c[i][j]){
            case 'H':
                tems.x=i;tems.y=j;
                tems.et=0;
                q.push(tems);
                break;
            case 'M':
                sx=i;sy=j;
                break;
            case 'D':
                ex=i;ey=j;
                break;
            default:break;
            }
        }
    }
    prework();
    binary();

    return 0;
}

意想不到,写了很久很随意,调试了居然过了2333,深夜惊喜。

祝大家做题顺利,约会顺利嘿!

猜你喜欢

转载自blog.csdn.net/daddy_hong/article/details/80490736