2023河南萌新联赛第(一)场:河南农业大学 H - 迷宫探险
在与boss的最终决战之后,小蓝来到了冒险的最后一关,在他面前有一个n*m
的迷宫,迷宫中道路用 '.'
表示,墙壁则由 ‘#’
表示。小蓝初始在[1,1]
的位置,他只有到达[n,m]
才能开启最终的宝藏。小蓝现在迫不及待的想要开启宝藏,所以他想最短的时间内走出迷宫。现在迷宫内有一种特殊的装置 –“弹射器”。弹射器的格子用 ’*’
表示。当走到有弹射器的一格时,小蓝必须选择一个方向,弹射器会让他沿着这个方向弹射 x
个距离,不同弹射器的弹射距离可以不同。弹射后的格子如果超过迷宫边界或者是墙壁则不能选择这个方向。小蓝现在可以向上下左右四个方向走,每走一个格子需要消耗一个单位时间,弹射则不消耗时间。求最短需要多少时间小蓝才能走出迷宫。如果无法到达终点,输出 -1
。
弹射器的数量,位置和弹射距离将在输入中给出。起点和终点一定不是弹射器。
输入描述:
第一行两个整数
n
,
m
n, m
n,m,接下来
n
n
n 行,每行
m
m
m 个只包含 ’.’,’*’,’#’
的字符描绘迷宫。
接下来一行一个整数k,下面的k行每行三个整数x, y, w表示在[x,y]格子的弹射器能弹射的距离。
(
2
≤
n
≤
3000
,
2
≤
m
≤
3000
,
n
∗
m
≤
500000
,
0
≤
k
,
w
2≤n≤3000,2≤m≤3000, n*m≤500000, 0≤k, w
2≤n≤3000,2≤m≤3000,n∗m≤500000,0≤k,w 在
i
n
t
int
int 范围内)
输出描述:
一行一个整数
示例1
输入
3 2
.*
#.
..
1
1 2 2
输出
1
示例2
输入
2 2
.*
#.
1
1 2 2
输出
-1
#include<bits/stdc++.h>
using namespace std;
const int N = 3010;
char s[N][N];
bool st[N][N];
int g[N][N];
int n,m;
void dijkstra()
{
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
priority_queue<array<int,3>,vector<array<int,3>>,greater<array<int,3>>> Q;
Q.push({0,1,1});
while(!Q.empty())
{
auto t=Q.top();Q.pop();
if(st[t[1]][t[2]]) continue;
st[t[1]][t[2]]=1;
for(int i=0;i<4;i++)
{
int x,y,cnt;
if(s[t[1]][t[2]]=='.') x=t[1]+dx[i],y=t[2]+dy[i],cnt=1;
if(s[t[1]][t[2]]=='*') x=t[1]+dx[i]*g[t[1]][t[2]],y=t[2]+dy[i]*g[t[1]][t[2]],cnt=0;
if(x<1 || x>n || y<1 || y>m) continue;
if(st[x][y] || s[x][y]=='#') continue;
if(x==n && y==m)
{
cout<<t[0]+cnt;
return ;
}
Q.push({t[0]+cnt,x,y});
}
}
cout<<"-1";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>(s[i]+1);
int k;cin>>k;
while(k--)
{
int x,y,w;cin>>x>>y>>w;
g[x][y]=w;
}
dijkstra();
return 0;
}