题意
题目大意就是给定一个地图,给定一个起点和终点,要求我们以最小步数到达终点,其中不可以落入陷阱并且每步可以走 1 − − k 步 题目大意就是给定一个地图,给定一个起点和终点,要求我们以最小步数到达终点,其中不可以落入陷阱并且每步可以走1--k步 题目大意就是给定一个地图,给定一个起点和终点,要求我们以最小步数到达终点,其中不可以落入陷阱并且每步可以走1−−k步
思路
很明显是个
b
f
s
裸题
很明显是个bfs裸题
很明显是个bfs裸题
但要加点特殊的处理,因为每次都走
1
−
k
步,然后时间复杂度会是
O
(
n
m
k
)
但要加点特殊的处理,因为每次都走1-k步,然后时间复杂度会是O(nmk)
但要加点特殊的处理,因为每次都走1−k步,然后时间复杂度会是O(nmk)
这样会超时,而且不可以用
b
o
o
l
s
t
[
]
[
]
数组来判断是否遍历过,因为这样的话,前面遍历的点会对后面遍历的点产生影响,具体影响看例子
这样会超时,而且不可以用bool st[][]数组来判断是否遍历过,因为这样的话,前面遍历的点会对后面遍历的点产生影响,具体影响看例子
这样会超时,而且不可以用boolst[][]数组来判断是否遍历过,因为这样的话,前面遍历的点会对后面遍历的点产生影响,具体影响看例子
4 4 4
…#
.#.#
…
##…
1 1 3 4
在这个例子中我们可以看到,第一步被更新的是第一行和第一列标红的1,然后第二步是第三列黑色的2和第三行第二个绿色的二,这时候我们如果用bool st[][]数组来判断的话就break了,因为第三行第三列的2被第一行第一列的那个格子更新过了,这时候就得从第三行第三列开始更新终点了,这样终点的步数就是3了,也就是错了,所以我们不可以用bool st[][]来标记是否来过,在这个情况下我们应该继续用第三行第一列的红1继续更新这一行,这个博客主要就是用来记录下这个bug!!!找了很久才找到,以后知道了,原来bfs中找最短路不可以用bool st[][]还是得需要step[][],还有部分细节写道代码注释里面了
ac代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1010 + 10;
#define x first
#define y second
typedef pair<int, int> pii;
int n, m, k;
char a[N][N];
int step[N][N];
int s1, d1, s2, d2;
//一个究极bug,就是在bfs过程中之前的路径判断会对之后的产生影响,按照st数组做法
bool check(int xx, int yy, int x, int y)
{
if(x < 1 || x > n || y < 1 || y > m) return false;
if(step[x][y] == step[xx][yy]) return false;//这一句话是避免点重复判断,及时break
if(a[x][y] == '#') return false;
return true;
}
int bfs()
{
queue<pii> q;
q.push({s1, d1});
int dx[5] = {0, 0, 1, -1};
int dy[5] = {1, -1, 0, 0};
memset(step, 0x3f, sizeof(step));
step[s1][d1] = 0;
while(q.size())
{
pii t = q.front();
q.pop();
if(t.x == s2 && t.y == d2)
{
return step[s2][d2];
}
for(int i = 0; i < 4; i ++)
{
for(int p = 1; p <= k; p ++)
{
int tx = t.x + p*dx[i];
int ty = t.y + p*dy[i];
if(check(t.x, t.y, tx, ty))
{
//加上这一句话就把时间复杂度降到了O(n*m)
//因为bfs中第一次到的点就是最小距离的,所以每个点只会进一次队列
if(step[tx][ty] > step[t.x][t.y] + 1)
{
step[tx][ty] = step[t.x][t.y] + 1;
q.push({tx, ty});
}
}
else
break;
}
}
}
return -1;
}
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
{
scanf("%s", (a[i]+1));
}
cin >> s1 >> d1 >> s2 >> d2;
int res = bfs();
printf("%d\n", res);
return 0;
}