“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛-O题

版权声明:欢迎随便转载。 https://blog.csdn.net/a1214034447/article/details/74909613

题目链接:点击打开链接


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


阅读更多

没有更多推荐了,返回首页