UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)

时间:2023-03-09 00:07:03
UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)

Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

A robot has to patrol around a rectangular area which is in a form of mxn grid (m rows and n columns). The rows are labeled from 1 to m. The columns are labeled from 1 to n. A cell (ij) denotes the cell in row i and column j in the grid. At each step, the robot can only move from one cell to an adjacent cell, i.e. from (xy) to (x + 1, y), (xy + 1), (x - 1, y) or (xy - 1). Some of the cells in the grid contain obstacles. In order to move to a cell containing obstacle, the robot has to switch to turbo mode. Therefore, the robot cannot move continuously to more than k cells containing obstacles.

Your task is to write a program to find the shortest path (with the minimum number of cells) from cell (1, 1) to cell (mn). It is assumed that both these cells do not contain obstacles.

Input

The input consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 20. The following lines describe the data sets.

For each data set, the first line contains two positive integer numbers m and n separated by space (1UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)mnUVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)20). The second line contains an integer number k(0UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)kUVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)20). The ith line of the next m lines contains n integer aij separated by space (i = 1, 2,..., m;j = 1, 2,...,n). The value of aij is 1 if there is an obstacle on the cell (ij), and is 0 otherwise.

Output

For each data set, if there exists a way for the robot to reach the cell (mn), write in one line the integer number s, which is the number of moves the robot has to make; -1 otherwise.

Sample Input

3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0

Sample Output

7
10
-1 题解:求机器人走最短路线,而且可以穿越障碍。
一道典型的BFS遍历的题,用队列实现,找到满足条件的最短路线;
题意很好理解,实现时应该注意判断规定障碍个数和标记走过的点。
BFS比DFS要快很多,一个用队列实现,一个用递归实现,都可以用

BFS的AC代码
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=;
int n,m,k;
int a[maxn][maxn][maxn];
int b[maxn][maxn];
int dir[][]= {-,,,,,-,,};
struct node
{
int x,y,step,zhangai;
void boom(int nx,int ny,int nstep,int nzhangai)
{
x=nx;
y=ny;
step=nstep;
zhangai=nzhangai;
}
}; int bfs()
{
queue<node>q;
while(!q.empty())
q.pop();
node u,v;
u.boom(,,,); //起点
q.push(u);
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=; i<; i++)
{
int xx=u.x;
int yy=u.y;
int sstep=u.step;
int szhangai=u.zhangai;
xx+=dir[i][];
yy+=dir[i][];
sstep+=;
if(xx>n||xx<||yy>m||yy<)
continue;
if(b[xx][yy]==)
szhangai++;
else
szhangai=;
if(szhangai>k)
continue;
if(a[xx][yy][szhangai]==) //如果没有这一步会超时
continue;
if(xx==n&&yy==m)
return sstep;
v.boom(xx,yy,sstep,szhangai);
q.push(v);
a[xx][yy][szhangai]=;
}
}
return -;
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n,&m,&k);
memset(a,,sizeof(a)); //每次都要
for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
scanf("%d",&b[i][j]);
int total=bfs();
printf("%d\n",total);
}
return ;
}

下面的是在网上看的一个用dfs实现的,也很容易懂

#include<iostream>
#include<cstring>
using namespace std;
int n,m,k;
int b[][];
int a[][][];
int total;
int xx[]= {-,,,};
int yy[]= {,,,-}; void dfs(int x,int y,int step,int zhangai)
{
if(x == n - && y == m - )
{
total = min(total,step);
return ;
}
for(int i = ; i < ; i++)
{
int nx = x + xx[i];
int ny = y + yy[i];
int st = zhangai;
if(b[nx][ny] == ) st++;
else
st = ;
if(nx >= && nx < n && ny >= && ny < m)
{
if((a[nx][ny][st] < || a[nx][ny][st] > step + ) && st <= k)
{
a[nx][ny][st] = step + ;
dfs(nx,ny,step + ,st);
}
}
}
return ;
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(a,-,sizeof(a));
total = <<;
cin>>n>>m>>k;
for(int i = ; i < n ; i++)
for(int j = ; j < m ; j ++)
cin>>b[i][j];
dfs(,,,);
if(total != << )
cout<<total<<endl;
else
cout<<"-1"<<endl;
}
return ;
}