题目描述:
after的算法书的遗落在一个叫做AIJ的迷宫中了,这个迷宫有N*M个房间,迷宫的入口为(1,1),算法书遗落在(r,c)。迷宫中的房间有四种状态:空房间、无法进入的房间、有墨菲斯托存在的房间和有莉莉丝存在的房间。墨菲斯托会否定一切,而莉莉丝会诱惑人做一种叫做YK的活动。after是一个意志薄弱的人,他遇到了墨菲斯托和莉莉丝之后,便会变成眼神空洞的超级YK机器人。after每步可以从他当前的房间走至上下左右四个房间的其中一个房间。after害怕变成超级YK机器人,所以要尽快拿到算法书然后从入口逃离。问after最少需要走多少步才可以在不变成超级YK机器人的情况下从入口出发取回算法书并逃离迷宫?

输入描述:
第一行一个正整数T(T<=10),表示共有T组数据。
对于每组数据,第一行四个正整数N,M,r,c(1<=N,M<=1000;1<=r<=N;1<=c<=M)。
接下来N行,每行M个字符,每个表示房间的状态,“.”表示空房间,“*”表示无法进入的房间,“F”表示有墨菲斯托存在的房间,“M”表示有莉莉丝存在的房间。
数据保证(1,1)为“.”。

输出描述:
对每组数据输出一行,即after最少需要走的步数。若after无法取回算法书,则输出“IMPOSSIBLE”(不带引号)。
示例1:

1
4 4 4 3
..**
*F..
*.*.
*M.F

输出:

14

题意:after要去点r,c处去取他的魔法书,途中有两个字母一个是F一个是M这两个字母他最多只能遇到一个,也就是说遇到M就不能再遇到F,遇到F就不能再遇到M。
题解:在普通的bfs中改进一下即可
加两个记录状态的变量
如果遇到M,flagM就标记为true,如果flagM标记为true,那么他就不能再遇到F了(前提是flagF=true)
如果遇到F,flagF就标记为true,如果flagF标记为true,那么他就不能再遇到M了(前提是flagM=true)
这样的话我们开始进行正常的bfs就可以了,如果走到书籍的地方,那这样子直接更新mins然后返回true,输出mins即可

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1010;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
char a[maxn][maxn];
bool visited[maxn][maxn];
int n,m,r,c;
int mins=MaxN;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

struct wazxy{
    int x,y,steps;
    bool flagF,flagM;
    wazxy(int a,int b,int c,bool d,bool e){x=a,y=b,steps=c,flagF=d,flagM=e;}
};

bool bfs(){
    queue<wazxy> q;
    visited[1][1]=true;
    q.push(wazxy(1,1,0,false,false));
    while(!q.empty()){
        wazxy temp=q.front();
        q.pop();
        if(temp.x==r&&temp.y==c){
            mins=temp.steps;
            return true;
        }
        for(int i=0;i<4;i++){
            int nx=dx[i]+temp.x;
            int ny=dy[i]+temp.y;
            if(!visited[nx][ny]&&(a[nx][ny]=='.'||a[nx][ny]=='F'||a[nx][ny]=='M')){
                if(temp.flagM==true&&a[nx][ny]=='F') continue;
                if(temp.flagF==true&&a[nx][ny]=='M') continue;
                visited[nx][ny]=true;
                if(temp.flagM==false&&a[nx][ny]=='M') q.push(wazxy(nx,ny,temp.steps+1,false,true));
                else if(temp.flagF==false&&a[nx][ny]=='F') q.push(wazxy(nx,ny,temp.steps+1,true,false));
                else q.push(wazxy(nx,ny,temp.steps+1,temp.flagF,temp.flagM));
            }
        }
    }
    return false;
}
inline void init(){
    memset(visited,false,sizeof(visited));
    memset(a,-1,sizeof(-1));
    mins=MaxN;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        init();
        cin>>n>>m>>r>>c;
        for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
        if(bfs()) cout<<2*mins<<endl;
        else cout<<"IMPOSSIBLE"<<endl;
    }
}