UVA 1600 Patrol Robot(BFS扩展)

Patrol Robot

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

Submit Status

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 (1mn20). The second line contains an integer number k(0k20). 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

题目大意:

  这道题是说,给你一个n*m的0-1矩阵,你要做的就是在这个矩阵中,从(1,1)走到(n,m)所需要的最小步数,但是你有一个功能,就是可以连续穿过k个1。

解题思路:

  看到最少操作次数,想都不用想,直接上bfs,然后node的设计就是x,y,k,step,这个k要注意下。

  当我们扩展到下一层的时候a[tx][ty]==1的时候,newnode.kk = now.k-1;当a[tx][ty] == 0 的时候,newnode.kk = k;

  相当于这个机器人在下一步走到1的时候就减少一点血,当走到0的时候,就满血满蓝了。

  一开始在newnode.kk = now.kk - 1;和 now.kk-=1;的设计上挂掉了第二组样例,原因很简单,就是说,如果我把提前把newnode搞出来,而是一味

  的靠now.kk去更新的话,会产生错误的结果.

代码:

  1 # include<cstdio>
  2 # include<iostream>
  3 # include<queue>
  4 # include<cstring>
  5
  6 using namespace std;
  7
  8 # define MAX 23
  9
 10 int a[MAX][MAX];
 11 int nxt[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
 12 int book[MAX][MAX][MAX];
 13
 14 int n,m,k;
 15
 16 struct node
 17 {
 18     int x,y;
 19     int step;
 20     int kk;
 21 };
 22 queue<node>Q;
 23
 24 void init()
 25 {
 26     while (!Q.empty())
 27     {
 28         Q.pop();
 29     }
 30     memset(book,0,sizeof(book));
 31 }
 32
 33 int can_move( int x ,int y,int kk )
 34 {
 35     if ( x>=1&&x<=n&&y>=1&&y<=m&&book[x][y][kk]==0 )
 36         return 1;
 37     else
 38         return 0;
 39 }
 40
 41 int bfs ( node start )
 42 {
 43     init();
 44     if ( start.x==n&&start.y==m )
 45     {
 46         return start.step;
 47     }
 48
 49     Q.push(start);
 50     while ( !Q.empty() )
 51     {
 52         node now = Q.front();
 53         Q.pop();
 54         if ( now.kk < 0 )
 55             continue;
 56         for ( int i = 0;i < 4;i++ )
 57         {
 58             node newnode;
 59             int tx = now.x+nxt[i][0], ty = now.y+nxt[i][1];
 60             if ( a[tx][ty]==1 )
 61                 newnode.kk = now.kk-1;
 62             else
 63                 newnode.kk = k;
 64             if ( can_move(tx,ty,newnode.kk) )
 65             {
 66                 if ( tx==n&&ty==m )
 67                 {
 68                     return now.step+1;
 69                 }
 70                 newnode.x = tx; newnode.y = ty; newnode.step = now.step+1;
 71             if( newnode.kk >= 0 )
 72             {
 73                 Q.push(newnode);
 74                 book[tx][ty][newnode.kk] = 1;
 75             }
 76             }
 77         }
 78     }
 79
 80     return -1;
 81
 82
 83 }
 84
 85
 86
 87 int main(void)
 88 {
 89     int t;scanf("%d",&t);
 90     while ( t-- )
 91     {
 92         scanf("%d%d%d",&n,&m,&k);
 93         for ( int i = 1;i <= n;i++ )
 94         {
 95             for ( int j = 1;j <= m;j++ )
 96             {
 97                 scanf("%d",&a[i][j]);
 98             }
 99         }
100         node start;
101         start.x = 1; start.y = 1;start.step = 0; start.kk = k;
102         book[start.x][start.y][start.kk] = 1;
103         int ans = bfs(start);
104         if ( ans == -1 )
105             printf("-1\n");
106         else
107             printf("%d\n",ans);
108
109     }
110
111     return 0;
112 }
时间: 2024-10-07 02:47:38

UVA 1600 Patrol Robot(BFS扩展)的相关文章

Uva 1600 Patrol Robot (BFS 最短路/DFS剪枝)

这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #include <bits/stdc++.h> using namespace std; struct Node{ int r; int c; int g; int cnt; Node(int r,int c,int g,int cnt):r(r),c(c),g(g),cnt(cnt){} }; int v

UVa 1600 Patrol Robot(BFS)

题意: 给定一个n*m的图, 有一个机器人需要从左上角(1,1)到右下角(n,m), 网格中一些格子是空地, 一些格子是障碍, 机器人每次能走4个方向, 但不能连续穿越k(0<= k <= 20)个障碍物, 求最短路径, 如无法到达输出 -1. 分析:   对于空地, 建一个vis数组记录走过的空地, 然后每次碰到没vis过的空地都把队伍K更新为最大值, vis这块地. 对于墙的情况, 我们可以建一个vis1数组去记录通过墙时候的k值, 如果之前有一个k值比现在要通过的大, 那么我们就不入队,

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

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 colu

UVA 1600 Patrol Robot

带状态的bfs 用一个数(ks)来表示状态-当前连续穿越的障碍数: step表示当前走过的步数: visit数组也加一个状态: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 7 const int maxn = 30 ; 8 9 struct node { 10 int x,y; 11 int

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

原题: 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 (i, j) denotes the cell in row i and column j in the

UVa 1600 Patrol Robot (习题 6-5)

传送门: https://uva.onlinejudge.org/external/16/1600.pdf 多状态广搜 网上题解: 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰到墙,当前的k减去1,碰到0,当前的k变成最初的k. vis[x][y][z]  x, y代表坐标  z表示k  当为真时说明该点剩余穿墙次数为k的状态已出现过 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef struct

1600 - Patrol Robot(BFS)

BFS题,不过多了一个很有意思的条件:不能连续穿越K个障碍,就好像多了一个技能一样,我用pre[][]数组来记录目前的k值: #include<bits/stdc++.h> using namespace std; int a[30][30],T,m,n,k,d[30][30],pre[30][30],air[10]={1,0,-1,0},air2[10]={0,1,0,-1};; typedef pair<int,int> P; P s[450]; int bfs() { que

【UVa】1600 Patrol Robot(dfs)

题目 题目 ? ? 分析 bfs可以搞,但是我还是喜欢dfs,要记忆化不然会T ? ? 代码 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF=1<<25; int k,n,m,map[25][25],dx[10]={1,-1,0,0},dy[10]={0,0,1,-1},ans; int vis[25][25][25];

UVA 1600 Patrol Robert

非常适合A*的一道题. 比普通的迷宫问题加一个信息k表示当前穿过的障碍物的数量. #include<cstdio> #include<cstring> #include<queue> using namespace std; const int MAX = 21; int m,n,k; int C[MAX][MAX][MAX]; int G[MAX][MAX]; int tarx,tary; struct node { int g,h; int x,y;//对于本题 x