J - Patrol Robot (dfs || bfs)

A robot has to patrol around a rectangular area which is in a form of m × n grid (m rows and n columns). The rows are labeled from 1 to m. The columns are labeled from 1 to n. A cell (i,j) 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 (x,y) to (x + 1,y), (x,y + 1), (x−1,y) or (x,y −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 (m,n). 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 ≤ m,n ≤ 20). The second line contains an integer number k (0 ≤ k ≤ 20). The i-th 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 (i,j), and is ‘0’ otherwise.

Output
For each data set, if there exists a way for the robot to reach the cell (m,n), 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

题意:在m*n的地图上,有障碍物(1)和空地(0),机器人要通过走上下左右四个方向从左上角(1,1)走到右下角(n,m),但不能连续超过k个障碍,要求最短步数。

解析:
        比较明显的搜索题,深搜宽搜都可以,本题关键在于 vis 标记数组要开三维,前两维记录坐标,第三维记录已经破除障碍物的数量,数组值表示走的步数。
         在这题中,机器人走路会有更多的分支选择,比如在走到同一点,有两种同一步数的走法,但是到达这一点所破除的障碍数量却不同,在这里我们需要选择障碍物更少的,因为很有可能在以后破除障碍能更快到达终点。到达相同点并且破除障碍物数量相同时,应该选择步数最小的。

AC代码:

DFS:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <set>
#include <bitset>
#include <vector>
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int min3(int a,int b,int c){return min(min(a,b),c);}
int max3(int a,int b,int c){return max(max(a,b),c);}
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}
ll qpow(ll a, ll b){ll s=1;while(b>0){if(b%2==1)s=s*a;a=a*a;b=b>>1;}return s;}
// a^b;

int mp[25][25];
int vis[25][25][25];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int n, m, k;

int dfs(int x, int y, int step, int pok)
{
    if(x==n && y==m)
        return step;

    int ans=inf;

    for(int i=0; i<4; i++)
    {
        int tx=x+dx[i];
        int ty=y+dy[i];
        int tp=pok;
        if(mp[tx][ty]==1) tp++;
        else tp=0;
        if(tx>=1 && tx<=n && ty>=1 && ty<=m)
        {
            if((vis[tx][ty][tp]==0 || vis[tx][ty][tp]>step+1) && tp<=k)
            {
                vis[tx][ty][tp]=step+1;
                ans=min(ans, dfs(tx, ty, step+1, tp));
            }
        }
    }
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n, &m, &k);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d", &mp[i][j]);

        ms(vis,0);
        int ans=dfs(1,1,0,0);

        if(ans==inf) puts("-1");
        else  printf("%d\n",ans);

    }
    return 0;
}


BFS:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <set>
#include <bitset>
#include <vector>
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3fLL
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}
ll qpow(ll a, ll b){ll s=1;while(b>0){if(b%2==1)s=s*a;a=a*a;b=b>>1;}return s;}
// a^b;

int mp[25][25], vis[25][25][25];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int ans, n, m, k;
struct node{
    int x, y, stp;
    int k;
};
int bfs()
{
    queue<node>q;
    node tp;
    tp.x=1, tp.y=1, tp.k=k, tp.stp=0;
    vis[tp.x][tp.y][k]=1;
    q.push(tp);
    while(!q.empty())
    {
        tp=q.front();
        q.pop();
        if(tp.x==n && tp.y==m)
        {
            ans=tp.stp;
            return 0;
        }
        for(int i=0; i<4; i++)
        {
            node tp1;
            tp1.x=tp.x+dx[i];
            tp1.y=tp.y+dy[i];
            tp1.stp=tp.stp+1;

            if(mp[tp1.x][tp1.y]) tp1.k=tp.k-1;
            else tp1.k=k;
            if(tp1.x>0 && tp1.x <=n && tp1.y>0 && tp1.y<=m && !vis[tp1.x][tp1.y][tp1.k])
            {
                if(tp1.k>=0)
                {
                    q.push(tp1);
                    vis[tp1.x][tp1.y][tp1.k]=1;
                }
            }
        }
    }
    if(q.empty()) ans=-1;
}
int main()
{
    int t; cin>>t;
    while(t--)
    {
        cin>>n>>m>>k;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                cin>>mp[i][j];
        ms(vis,0); bfs();
        cout<<ans<<endl;
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/Vitamin_R/article/details/80627478