题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4475
题目大意:机器人从一个m*n矩阵的(1,1)到(m,n)。矩阵中的0代表空地,1代表障碍物。机器人每次可以向四个方向走一格,机器人可以穿过障碍物,但是不能连续穿过k个障碍物,求最短路长度。起点和终点确保是空地。
分析:求最短路径首先就能想到是dfs,就是这个题增加了一个可以穿越障碍物的条件,所以可以在原来的记忆搜索矩阵的基础上增加一维矩阵,也即是说前两个rank存放的是x,y坐标,第三个rank存放的是穿越障碍物的数量,三维矩阵中存放的是步数,有了这个矩阵辅助,问题就变得很简单了。
ac代码
#include<cstdio>
#include<cstring>
#define Max 25
int maze[Max][Max];
int vis[Max][Max][Max];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int m, n, k;
int min(int x, int y)
{
if(x < y)return x;
else return y;
}
int dfs(int x, int y, int step, int pk)
{
if(x == m && y == n)return step;
int minstep = m * n + 1;
for(int i = 0; i < 4; i++)
{
int xx = dx[i] + x;
int yy = dy[i] + y;
int sstep = step + 1;
int ppk = pk;
if(maze[xx][yy] == 1)ppk = ppk + 1;
else ppk = 0;
if(xx >=1 && xx <= m && yy >= 1 && yy <= n)
{
if((vis[xx][yy][ppk] < 0 || vis[xx][yy][ppk] > sstep) && ppk <= k)
{
vis[xx][yy][ppk] = sstep;
minstep = min(minstep, dfs(xx, yy, sstep, ppk));
}
}
}
return minstep;
}
int main()
{
int T;
scanf("%d", &T);
for(int t = 1; t <= T; t++)
{
scanf("%d %d", &m, &n);
scanf("%d", &k);
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &maze[i][j]);
memset(vis, -1, sizeof(vis));
int step = dfs(1, 1, 0, 0);
if(step == m * n + 1)printf("-1\n");
else printf("%d\n", step);
}
return 0;
}