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

本文解决UVA 1600 Patrol Robot问题,描述了在一个含障碍物的矩形网格中,寻找从左上角到右下角的最短路径。使用BFS和DFS两种方法进行遍历,详细介绍了代码实现,包括障碍物的处理和最短步数的计算。

                  UVA 1600 Patrol Robot

 
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 (1$ \le$mn$ \le$20). The second line contains an integer number k(0$ \le$k$ \le$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=21;
int n,m,k;
int a[maxn][maxn][maxn];
int b[maxn][maxn];
int dir[4][2]= {-1,0,1,0,0,-1,0,1};
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(1,1,0,0);         //起点
    q.push(u);
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            int xx=u.x;
            int yy=u.y;
            int sstep=u.step;
            int szhangai=u.zhangai;
            xx+=dir[i][0];
            yy+=dir[i][1];
            sstep+=1;
            if(xx>n||xx<1||yy>m||yy<1)
                continue;
            if(b[xx][yy]==1)
                szhangai++;
            else
                szhangai=0;
            if(szhangai>k)
                continue;
            if(a[xx][yy][szhangai]==1)  //如果没有这一步会超时
                continue;
            if(xx==n&&yy==m)
                return sstep;
            v.boom(xx,yy,sstep,szhangai);
            q.push(v);
            a[xx][yy][szhangai]=1;
        }
    }
    return -1;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d %d",&n,&m,&k);
        memset(a,0,sizeof(a));        //每次都要
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d",&b[i][j]);
        int total=bfs();
        printf("%d\n",total);
    }
    return 0;
}

 

 

 

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

#include<iostream>
#include<cstring>
using namespace std;
int n,m,k;
int b[21][21];
int a[21][21][21];
int total;
int xx[4]= {-1,1,0,0};
int yy[4]= {0,0,1,-1};

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

 

 

转载于:https://www.cnblogs.com/hfc-xx/p/4670089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值