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
**********************************************************************/