题目链接:点击打开链接
解题思路:题目告诉我们当然主人公够聪明,但是不知道传送门是怎么对应的,那么此时可以看做只有两个操作。一:不进入传送门直接走。二:进入离出发点最近的传送门(毕竟不知道肯定是选择最近的啊)。然后用一个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; }