您的位置:首页 > 其它

UVa 1600 Patrol Robot

2015-03-26 15:45 288 查看
A robot has to patrol around a rectangular area which is in a form of m x n grid (m rows and n columns).The rows are labeled from 1 tom. The columns are labeled from 1 to n. A cell (i, j) denotes the cell in row i andcolumn 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 thesecells 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 datasets.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
#include <cstdio>#include <queue>#include <cstring>#include <cstdlib>using namespace std;typedef struct t_node{int row, col;int have_num;	// 记录包括此步在内已经连续走的障碍块数目int total_num;	// 记录包括此步在内已经走的数目}t_node;// 记录整个区域情况int area[30][30];// 记录是否已经走过,flag[i][j][k]为1代表i,j并且包括此步在内已经连续走的障碍物数目为k已经走过,否则为未走过int flag[30][30][30];int row, col, k;queue<t_node*> my_queue;int main(){int n;scanf("%d", &n);int count = 0;while(count < n){memset(area, 0, sizeof(area));memset(flag, 0, sizeof(flag));my_queue = queue<t_node*>();// 读入各个情况scanf("%d %d %d", &row, &col, &k);for(int i = 1; i <= row; i++)for(int j = 1; j <= col; j++)scanf("%d", &area[i][j]);// 建立开始节点int find_flag = 0;t_node* p = (t_node*)malloc(sizeof(t_node));memset(p, 0, sizeof(p));p->row = 1;p->col = 1;/*		if(area[1][1] == 1)p->have_num = 1;elsep->have_num = 0;*/p->have_num = 0;p->total_num = 0;/*if(p->have_num == 1 && k == 0 && !(row == 1 && col == 1)){printf("-1\n");count++;continue;}*/my_queue.push(p);flag[1][1][0] = 1;// 进行广度优先搜索,来确定到终点需要的步数while(my_queue.size() > 0){t_node* p = my_queue.front();my_queue.pop();int n_row = p->row;int n_col = p->col;if(n_row == row && n_col == col){find_flag = 1;printf("%d\n", p->total_num);break;}// 查看该位置的周围四个位置是否可以走,如果可以走,加入队列if(n_row-1 >= 1){int now_num = 0;if(area[n_row-1][n_col] == 1)now_num = p->have_num + 1;if(now_num <= k && flag[n_row-1][n_col][now_num] == 0){t_node* q = (t_node*)malloc(sizeof(t_node));memset(q, 0, sizeof(q));q->row = n_row-1;q->col = n_col;q->total_num = p->total_num+1;q->have_num = now_num;my_queue.push(q);flag[n_row-1][n_col][now_num] = 1;}}if(n_row+1 <= row){int now_num = 0;if(area[n_row+1][n_col] == 1)now_num = p->have_num + 1;if(now_num <= k && flag[n_row+1][n_col][now_num] == 0){t_node* q = (t_node*)malloc(sizeof(t_node));memset(q, 0, sizeof(q));q->row = n_row+1;q->col = n_col;q->total_num = p->total_num+1;q->have_num = now_num;my_queue.push(q);flag[n_row+1][n_col][now_num] = 1;}}if(n_col-1 >= 1){int now_num = 0;if(area[n_row][n_col-1] == 1)now_num = p->have_num + 1;if(now_num <= k && flag[n_row][n_col-1][now_num] == 0){t_node* q = (t_node*)malloc(sizeof(t_node));memset(q, 0, sizeof(q));q->row = n_row;q->col = n_col-1;q->total_num = p->total_num+1;q->have_num = now_num;my_queue.push(q);flag[n_row][n_col-1][now_num] = 1;}}if(n_col+1 <= col){int now_num = 0;4000if(area[n_row][n_col+1] == 1)now_num = p->have_num + 1;if(now_num <= k && flag[n_row][n_col+1][now_num] == 0){t_node* q = (t_node*)malloc(sizeof(t_node));memset(q, 0, sizeof(q));q->row = n_row;q->col = n_col+1;q->total_num = p->total_num+1;q->have_num = now_num;my_queue.push(q);flag[n_row][n_col+1][now_num] = 1;}}}if(find_flag == 0)printf("-1\n");count++;}return 0;}
本来是很简单的BFS,加入了一个条件:不能连续走多于k个标为1的方块。
然后一直出错,后来发现自己想法有问题,多了一个条件后,当一个点(i,j)是否被搜索过就不能这样简单判断了,需要加上到达这个点时已经连续走过的1的块的数目。
比如,到达(2,2)时连续走过1的块为1个和2个是不一样的。多了一维状态,以后在判断一个状态是否被遍历过时,需要仔细想请楚!

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: