方格迷宫
方格迷宫
给定一个 行 列的方格矩阵。
行从上到下依次编号为 ,列从左到右依次编号为 。
第 行第 列的方格表示为 。
矩阵中的方格要么是空地(用 . 表示),要么是陷阱(用 # 表示)。
初始时,你位于方格 ,你需要前往方格 。
每次移动,你可以任选上、下、左、右四个方向之一,并沿该方向移动 步。
从一个方格移动至相邻方格视为一步。
但是,你要保证在你的移动过程中不能走出矩阵,也不能进入陷阱方格。
请你计算从方格 移动至方格 ,所需要的最少移动次数。
保证方格 和方格 都是空地。
方格 和方格 可能是同一个方格。
注意:注意区分本题中移动次数与移动步数的区别。
输入格式
第一行包含三个整数 。
接下来 行,每行包含 个字符,其中第 行第 个字符,要么是 .,表示方格 是空地;要么是 #,表示方格 是陷阱。
最后一行包含四个整数 。
输出格式
一个整数,表示所需要的最少移动次数。
如果无法从方格 移动至方格 ,则输出 。
数据范围
前 个测试点满足 。
所有测试点满足 ,,。
输入样例1:
3 4 4 .... ###. .... 1 1 3 1
输出样例1:
3
输入样例2:
3 4 1 .... ###. .... 1 1 3 1
输出样例2:
8
输入样例3:
2 2 1 .# #. 1 1 2 2
输出样例3:
-1
解题思路
很容易想到,然后在枚举个方向时再枚举这个方向要走的长度,因此这样做的时间复杂度为。这题有个比较巧妙的剪枝,假设当前位置是,到该位置的距离是,在同一个方向上枚举要走的长度,当枚举到位置且有,那么之后的格子可以用这个位置来更新,因为,因此有,因此用来更新同一个方向之后的格子最小距离不会变大。所以在枚举的过程中发现直接就好了。
加上这个剪枝后时间复杂度就变成了。可以证明在同一个方向上每个格子最多会被枚举到次(一次是第一次枚举到该格子并更新距离,另外一次是从距离更大的格子枚举到并),因此个方向所有格子一共最多被枚举次。
假设距离为的格子已经沿着一个方向把一些格子更新成了,此时再从队列中弹出一个格子(下图红色格子),根据的性质这个格子的距离一定,因此当这个格子枚举到距离为的格子或者已经被更新为的格子时就会掉。
其中上图右边的红色格子更具体来说应该是。首先不可能是,否则下面距离为的白色格子走到这个红色格子就会掉,就不会更新到上面那些距离为的格子了。而红色格子又是距离为的白色格子上面的格子,因此就会被更新为,所以红色格子的距离应该就是。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int, int> PII; 5 6 const int N = 1010; 7 8 char g[N][N]; 9 int dist[N][N]; 10 PII q[N * N]; 11 int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 12 13 int main() { 14 int n, m, k, x1, y1, x2, y2; 15 scanf("%d %d %d", &n, &m, &k); 16 for (int i = 0; i < n; i++) { 17 scanf("%s", g + i); 18 } 19 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 20 x1--, y1--, x2--, y2--; 21 memset(dist, 0x3f, sizeof(dist)); 22 dist[x1][y1] = 0; 23 int hh = 0, tt = -1; 24 q[++tt] = {x1, y1}; 25 while (hh <= tt) { 26 PII t = q[hh++]; 27 for (int i = 0; i < 4; i++) { 28 for (int j = 1; j <= k; j++) { 29 int x = t.first + dx[i] * j, y = t.second + dy[i] * j; 30 if (x < 0 || x >= n || y < 0 || y >= m) break; 31 if (g[x][y] == '#') break; 32 if (dist[x][y] < dist[t.first][t.second] + 1) break; 33 if (dist[x][y] > dist[t.first][t.second] + 1) { 34 dist[x][y] = dist[t.first][t.second] + 1; 35 q[++tt] = {x, y}; 36 } 37 } 38 } 39 } 40 printf("%d", dist[x2][y2] == 0x3f3f3f3f ? -1 : dist[x2][y2]); 41 42 return 0; 43 }
参考资料
AcWing 4943. 方格迷宫(第二届ACC(AcWing Cup)全国联赛):https://www.acwing.com/video/4683/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17287759.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-04-04 牛奶工厂