2023河南萌新联赛第(一)场:河南农业大学 H - 迷宫探险

该问题是一个基于图的最短路径问题,迷宫中的每个节点代表一个位置,.是可通行的路径,#是墙壁,*是弹射器。小蓝需要找到从起点到终点的最短时间,弹射器允许他在特定方向上快速移动。Dijkstra算法被用来寻找最短路径,考虑了弹射器的移动效果。当无法到达终点时,输出-1。
摘要由CSDN通过智能技术生成

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 2n3000,2m3000,nm500000,0k,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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wa_Automata

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值