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 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 (1m, n20). 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 (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
解题思路:
一开始利用DFS搜索符合条件的路径,结果超时了,之后改用BFS
思路是保留每个坐标连续1的个数(遇到1让前结点+1,遇到0则清0,遍历的过程中,如果坐标遇到1的个数超过了K,那么这个结点直接出队不再处理,遍历到终点时,输出当前层数,如果不能到达终点,则输出-1)
#include <iostream>
#include <algorithm>
#include <queue>
#include <stdio.h>
#include <string>
#include <string.h>
using namespace std;
const int MAXN = 25;
int rbMap[MAXN][MAXN];
bool visited[MAXN][MAXN]; //设置访问
int cN;
int m,n,k;
int mmovex[4] = {0,0,1,-1};
int mmovey[4] = {1,-1,0,0};
struct xpos{
int x,y;
int cumK;
xpos(int _x,int _y){
x = _x;
y = _y;
cumK = 0; //初始化为0
}
};
int main(){
scanf("%d",&cN); //几组测试用例
while(cN--){ //减去
memset(visited,false,sizeof(visited)); //设置未被访问
scanf("%d %d",&m,&n);
scanf("%d",&k); //限制的栅栏数
for(int i = 1; i <= m;++i){
for(int j = 1; j <= n;++j){
scanf("%d",&rbMap[i][j]); //扫描
}
}
//广度优先
bool isdes = false;
queue<xpos> bfs_queue; //广度优先队列
queue<int> layer_queue; //距离队列
int curLayer = 0;
int finalfis = 0;
xpos startP(1,1);
bfs_queue.push(startP);
layer_queue.push(0);
while(!bfs_queue.empty()){
xpos curPos = bfs_queue.front(); //队首
curLayer = layer_queue.front();
bfs_queue.pop();
layer_queue.pop();
//判断是否到达终点
visited[curPos.x][curPos.y] = true;
if(curPos.x == m && curPos.y == n){
finalfis = curLayer;
isdes = true;
break;
}
for(int i = 0; i < 4; ++i){
int newX = curPos.x + mmovex[i];
int newY = curPos.y + mmovey[i];
if(newX > 0 && newX <= m && newY > 0 && newY <= n &&!visited[newX][newY]){
xpos newPos(newX,newY);
if(rbMap[newX][newY] == 1){
newPos.cumK = curPos.cumK+1;
if(newPos.cumK > k) continue;
}else{
newPos.cumK = 0; //归零操作
}
bfs_queue.push(newPos);
layer_queue.push(curLayer+1); //层数+1
}
}
}
if(isdes){
printf("%d\n",finalfis);
}else{
printf("-1\n");
}
}
return 0;
}