题目链接:点击打开链接
解题思路:题目告诉我们当然主人公够聪明,但是不知道传送门是怎么对应的,那么此时可以看做只有两个操作。一:不进入传送门直接走。二:进入离出发点最近的传送门(毕竟不知道肯定是选择最近的啊)。然后用一个bfs套dfs将传送门出口作为新的出发点,看看是否能到达终点,若有一种不能则为-1.
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 1e2+10,co[4][2]={1,0,0,1,-1,0,0,-1};
int n,m,cnt1,ans;
char map[mx][mx];
struct node{
int x,y,k;
node(){}
node(int xx,int yy,int kk){ x = xx, y = yy, k = kk; }
}a[5],b[5];
bool vis2[5];
int bfs(int beg,int eng){
queue<node> skt;
bool vis[mx][mx],flag = 0;
int sum = inf;
memset(vis,0,sizeof(vis));
skt.push(node(beg,eng,0));
vis[beg][eng]=1;
while(!skt.empty()){
node no = skt.front();
skt.pop();
for(int i=0;i<4;i++){
node po = node(no.x+co[i][0],no.y+co[i][1],no.k+1);
if(po.x<0||po.y<0||po.x>=n||po.y>=m) continue;
if(vis[po.x][po.y]||map[po.x][po.y]=='#') continue;
vis[po.x][po.y] = 1;
if(map[po.x][po.y]=='T') return min(sum,po.k);
if(!flag&&map[po.x][po.y]=='i'){
map[po.x][po.y] = '.';
for(int j=0;j<cnt1;j++){
if(vis2[j]) continue;
vis2[j] = 1;
if(sum==inf) sum = bfs(b[j].x,b[j].y)+po.k+1;
else sum = max(sum,bfs(b[j].x,b[j].y)+po.k+1);
vis2[j] = 0;
}
map[po.x][po.y] = 'i';
flag = 1;
}
skt.push(po);
}
}
return sum;
}
int main(){
int t,beg,eng;
scanf("%d",&t);
while(t--){
ans = 0, cnt1 = 0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%s",map[i]);
for(int j=0;j<m;j++){
if(map[i][j]=='S') beg = i, eng = j;
else if(map[i][j]=='o') b[cnt1++]=node(i,j,0);
}
}
ans = bfs(beg,eng);
printf("%d\n",ans>=inf? -1:ans);
}
return 0;
}