UVa 1600 Patrol Robot(bfs)——BFS 练习

Examination Questions:

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

0 0

Sample Output

7

10

-1

Question Means:

Robot 要从一个m*n(1≤m,n≤20)网格的左上角(1,1)走到右下角(m,n)并且不能连续穿越k个障碍,求最短路长。

My Thoughts:

运用广搜(bfs)解题可以很好的控制时间复杂度,防止超时。


Code:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N=20+10;
int mapa[N][N];
int vis[N][N][N];
int mapx[5]={1,0,-1, 0};
int mapy[5]={0,1, 0,-1};
struct node
{
	int x,y,step,k;
};
int n,m,k,num;
void bfs();
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		memset(mapa,0,sizeof(mapa));//清空数组。 
		memset(vis,0,sizeof(vis));
		cin>>n>>m>>k;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			cin>>mapa[i][j];
		bfs();
		cout<<num<<"\n";	
	}
	return 0;
}
void bfs() 
{
  queue<node>q;
  node temp;
  temp.x=1,temp.y=1,temp.k=k,temp.step=0;
  vis[temp.x][temp.y][k]=1;
  q.push(temp);//入队 
  while(!q.empty()) 
  {
  	temp=q.front();//读取队列中第一个元素 
    q.pop();//移除队列中的第一个元素
    if(temp.x==n&&temp.y==m)//如果到达目的地,输出路径长度,跳出循环。 
    {
    	num=temp.step; 
    	return;
	}
	if(temp.k>=0)//用来判定是否有解。 
	for(int i=0;i<4;i++)//四次循环判定四个方向。 
	{
		node temp1;
		temp1.x=temp.x+mapx[i];
		temp1.y=temp.y+mapy[i];
		temp1.step=temp.step+1;
		if(mapa[temp1.x][temp1.y])//判断是否为障碍物。 
		temp1.k=temp.k-1;//是,连续穿越量减去1。 
		else
		temp1.k=k;//否,连续穿越量回满! 
		if(temp1.x>0&&temp1.x<=n&&temp1.y>0&&temp1.y<=m&&!vis[temp1.x][temp1.y][temp1.k])//判断是否越界,并判断这个点是否已经走过。 
		{
		    if(temp1.k>=0)
			{
			    q.push(temp1);
				vis[temp1.x][temp1.y][temp1.k]=1;	
			}	
		}
	}  
  }
  if(q.empty())//无解输出-1。 
  num=-1;	
} 

猜你喜欢

转载自blog.csdn.net/Genius_panda_ACM/article/details/81587554