这道题的解法非常妙。
一开始,我的想法是:在bfs是搜索过程中带着状态变量con(表示是否遇到过墨菲斯托或莉莉丝,两个都遇到了这个路线就不成立,可以pop掉。)但是发现这样vis数组会其冲突,压缩起来会比较麻烦。
参考大佬的解法:分两次bfs
第一次,将墨菲斯托的位置全部设为无法进入,莉莉丝设为空房间,bfs一次,得出最短路。这一步的目的是:求出不经过墨菲斯托所在位置能不能得到书,能的话,返回最短距离,不能则返回-1。
第二次反过来,墨菲斯托设为空房间,莉莉丝设为无法进入,再进行一次bfs。同样的,这一步的求出不经过莉莉丝能不能得到书。
然后,综合两次结果得出结论:
若两个结果都是-1,说明不管怎么走,都会遇到墨菲斯托,并且都会遇到莉莉丝,因此,IMPOSSIBLE
若只有其中一个不是-1,说明一个是一定要遇到的,另一个可以不遇到,那就输出不为-1的那一个。
否则,两个都不是-1,都可以不遇到,那当然取min的那个。
为什么这道题可以这么做呢?因为两个人中一定需要有一个遇不到才存在可行方案,所以,我们可以分两次bfs,得出是否存在方案可以避开两人中的一人,来判断是不是IMPOSSIBLE。
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=1e3+10;
int t,n,m,r,c;
struct node{
int x,y,step;
node(int xx,int yy,int sp){
x=xx,y=yy,step=sp;
}
};
char a[maxn][maxn];
char mp[maxn][maxn];
int vis[maxn][maxn]={0};
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int bfs(){
memset(vis,0,sizeof(vis));
queue<node> que;
que.push(node(1,1,0));
vis[1][1]=1;
while(!que.empty()){
node a=que.front();
que.pop();
if(a.x==r&&a.y==c){
return 2*a.step;
}
rep(i,0,3){
int dx=a.x+dir[i][0],dy=a.y+dir[i][1];
if(vis[dx][dy]||dx<=0||dy<=0||dx>n||dy>m||mp[dx][dy]=='*') continue;
vis[dx][dy]=1;
node tmp(dx,dy,a.step+1);
que.push(tmp);
}
}
return -1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//===========================================================
read(t);
while(t--){
memset(vis,0,sizeof(vis));
read(n),read(m),read(r),read(c);
rep(i,1,n){
rep(j,1,m){
cin>>a[i][j];
}
}
rep(i,1,n){
rep(j,1,m){
if(a[i][j]=='M'){
mp[i][j]='*';
}
else if(a[i][j]=='F'){
mp[i][j]='.';
}
else mp[i][j]=a[i][j];
}
}
int ans1=bfs();
rep(i,1,n){
rep(j,1,m){
if(a[i][j]=='F'){
mp[i][j]='*';
}
else if(a[i][j]=='M'){
mp[i][j]='.';
}
else{
mp[i][j]=a[i][j];
}
}
}
int ans2=bfs();
if(ans1==-1&&ans2==-1){
puts("IMPOSSIBLE");
}
else if(ans1==-1||ans2==-1){
write(max(ans1,ans2)),putchar('\n');
}
else{
write(min(ans1,ans2)),putchar('\n');
}
}
//===========================================================
return 0;
}
京公网安备 11010502036488号