[NC15665]maze

news/2024/7/1 9:36:43

题目描述:
小明来到一个由n x m个格子组成的迷宫,有些格子是陷阱,用’#‘表示,小明进入陷阱就会死亡,’.'表示没有陷阱。小明所在的位置用’S’表示,目的地用’T’表示。

小明只能向上下左右相邻的格子移动,每移动一次花费1秒。

有q个单向传送阵,每个传送阵各有一个入口和一个出口,入口和出口都在迷宫的格子里,当走到或被传送到一个有传送阵入口的格子时,小明可以选择是否开启传送阵。如果开启传送阵,小明就会被传送到出口对应的格子里,这个过程会花费3秒;如果不开启传送阵,将不会发生任何事情,小明可以继续向上下左右四个方向移动。

一个格子可能既有多个入口,又有多个出口,小明可以选择任意一个入口开启传送阵。使用传送阵是非常危险的,因为有的传送阵的出口在陷阱里,如果小明使用这样的传送阵,那他就会死亡。也有一些传送阵的入口在陷阱里,这样的传送阵是没有用的,因为小明不能活着进入。请告诉小明活着到达目的地的最短时间。

题解:
这里与平时bfs不同的一点是,他可以进行传送,但是这个传送他耗费的时间是3s,跟普通移动是不一样的,所以可能存在花费时间长但是移动距离却不如普通移动的距离远的问题,所以这里我们就不可以用普通的队列来解决这个问题了,想一下bfs队列里面的思想,就是考花费时间短的在队列前面从而解决的问题,所以我们这里可以用到优先队列(按照其花费时间由小到大排序)。
还有一个问题是如何记录传送门呢?
我们可以开一个二维结构体来记录,如果对应的坐标有相应的结果,那么我们就可以把他直接传到对应的位置,耗时3s,在继续进行普通的走动。
要注意一点就是通过传送门传过去那一点你是不可以把他标记为false的,因为你不确定是不是普通的移动比他耗时还少。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 310;
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,q;
int mins=MaxN;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct wazxy{int x,y,steps;wazxy(int a,int b,int c){x=a,y=b,steps=c;}bool operator < (const wazxy & a)const{return steps>a.steps;}
};
struct door{int x,y;
}ma[maxn][maxn];
void init(){memset(visited,false,sizeof(visited));memset(a,-1,sizeof(a));memset(ma,0,sizeof(ma));mins=MaxN;
}
bool bfs(int x,int y){priority_queue<wazxy> q;q.push(wazxy(x,y,0));while(!q.empty()){wazxy temp=q.top();q.pop();if(a[temp.x][temp.y]=='T'){mins=temp.steps;return true;}if(ma[temp.x][temp.y].x!=0&&!visited[ma[temp.x][temp.y].x][ma[temp.x][temp.y].y]&&a[ma[temp.x][temp.y].x][ma[temp.x][temp.y].y]!='#'){q.push(wazxy(ma[temp.x][temp.y].x,ma[temp.x][temp.y].y,temp.steps+3));}for(int i=0;i<4;i++){int nx=temp.x+dx[i];int ny=temp.y+dy[i];if(!visited[nx][ny]&&(a[nx][ny]=='.'||a[nx][ny]=='T')){visited[nx][ny]=true;q.push(wazxy(nx,ny,temp.steps+1));}}}return false;
}int main()
{while(cin>>n>>m>>q){init();for(int i=1;i<=n;i++){scanf("%s",a[i]+1);}for(int i=0;i<q;i++){int x,y,ex,ey;scanf("%d%d%d%d",&x,&y,&ex,&ey);x++,y++,ex++,ey++;ma[x][y].x=ex,ma[x][y].y=ey;}bool flag=false;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]=='S'){if(bfs(i,j)) flag=true;}}}if(flag) cout<<mins<<endl;else cout<<-1<<endl;}
}

http://lihuaxi.xjx100.cn/news/285800.html

相关文章

ZOJ 3329 One Person Game 带环的概率DP

每次都和e[0]有关系 通过方程消去环 dp[i] sigma(dp[ik]*p)dp[0]*p1 dp[i] a[i]*dp[0]b[i] dp[i] sigma(p*(a[ik]*dp[0]b[ik]))dp[0]*p1 a[i] sigma(a[ik]*p)p b[i] sigma(b[ik]*p)1 #include <cstdio> #include <cstring> using namespace std; double A[555…

从git仓库中删除.idea文件夹的小技巧

这篇文章主要介绍了从git仓库中删除.idea文件夹的小妙招,本文给大家介绍的非常详细&#xff0c;对大家的学习或工作具有一定的参考借鉴价值&#xff0c;需要的朋友可以参考下 如果不配置.gitignore的文件&#xff0c;带push代码的时候就会把一写不必要的文件push到远程仓库&…

高精度模拟乘法阶乘

方法一&#xff1a;自己写的较繁琐的一种方法 #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxx1e510; char s1[maxx],s2[maxx]; int a[maxx],b[maxx]; int c[maxx]; int n; int main…

命令行的艺术 (GitHub 星标 6 万多)

转自&#xff1a;GitHubgithub.com/jlevy/the-art-of-command-line/blob/master/README-zh.md熟练使用命令行是一种常常被忽视&#xff0c;或被认为难以掌握的技能&#xff0c;但实际上&#xff0c;它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时&…

微软小冰:全双工语音对话详解

讲师 | 周力来源 | AI科技大本营在线公开课微软小冰第六代发布会上正式宣布上线全新的共感模型&#xff0c;同时也开始公测一种融合了文本、全双工语音与实时视觉的新感官。这项新技术可以实时预测人类即将说出的内容&#xff0c;实时生成回应&#xff0c;并控制对话节奏&#…

简单介绍六点nginx优化的方法

这篇文章主要介绍了nginx优化的六点方法,有对nginx优化不太熟悉的同学可以参考下 一.优化Nginx并发量 [rootproxy ~]# ab -n 2000 -c 2000 http://192.168.4.5/ Benchmarking 192.168.4.5 (be patient) socket: Too many open files (24) //提示打开文件数量过多 修改Ngin…

给Chrome“捉虫”16000个,Google开源bug自检工具

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 在内部开发和使用八年之久&#xff0c;近日&#xff0c;Google 宣布开源 bug 自动化检测工具 ClusterFuzz。ClusterFuzz 是一款提供端到端的自动化模糊测试工具&#xff1a;从错误检测到分类排查&…

Codeforces Round #649 (Div.2)题解

文章目录A - XXXXXB - Most socially-distanced subsequenceC - Ehab and Prefix MEXsA - XXXXX 题意&#xff1a;这个题让你找从开头或者是结尾去掉最少几个数以后总和是不能整除给定的x 思路&#xff1a;如果这个序列总和可以整除给定的x的话&#xff0c;那么我们只要找到一…