概述
Description
给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
Input
第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x 1, y 1, x 2, y 2 (1 ≤ k ≤ 10, 1 ≤ x 1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能转的弯数,(x 1, y 1), (x 2, y 2)表示两个位置,其中x 1,x 2对应列,y 1, y 2对应行。
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x 1, y 1, x 2, y 2 (1 ≤ k ≤ 10, 1 ≤ x 1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能转的弯数,(x 1, y 1), (x 2, y 2)表示两个位置,其中x 1,x 2对应列,y 1, y 2对应行。
Output
每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input
2 5 5 ...** *.**. ..... ..... *.... 1 1 1 1 3 5 5 ...** *.**. ..... ..... *.... 2 1 1 1 3
Sample Output
no yes
解析:
原来以为这题是一道比较基本的BFS题目,但是WA了,n发,无奈,只好百度了一下题解。
这道题目的方法很巧妙是用一个标记数组配合BFS来标记转向的次数。
比如这种样例子的情况 ...** *.**. ..... ..... *.... 2 1 1 1 3
先全部初始化为 0
然后从第一个节点开始搜索,并用标记数组来标记转向的次数,遇到0就标记
21100
02000
32333
02000
02000
当遇到终点,而且标记的位置的数 <= k 返回true
这真是一个很巧妙的方法。万万没想到啊。
原来的做法是参考了,UVA上的独轮车那题,用了一个三维的标记数组来标记位置和方向。每个位置都BFS一次。
但是不知道为什么样例都过了,用这个方法交WA了n发。我还是太年轻了……
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int k,x1,y1,x2,y2;
int m,n;
//上 左 下 右
const int dr[] = {-1, 0, 1, 0};
const int dc[] = { 0,-1, 0, 1};
const int N = 110;
struct Node{
int r;
int c;
Node(int r,int c) {
this->r = r;
this->c = c;
}
};
int vis[N][N]; //这个数组用于保存拐弯的次数
char grid[N][N];
bool bfs() {
memset(vis,0,sizeof(vis)); //初始化开始所有的拐弯次数为0
queue<Node> q;
q.push(Node(y1,x1));
int r,c;
while( !q.empty()) {
Node front = q.front();
q.pop();
for(int i = 0; i < 4; i++) {
r = front.r + dr[i];
c = front.c + dc[i];
while( r >= 0 && r < m && c >= 0 && c < n && grid[r][c] != '*') {
if(vis[r][c] == 0) {
vis[r][c] = vis[front.r][front.c] + 1;
if( r == y2 && c == x2 && vis[r][c] <= k+1) {
return true;
}
q.push(Node(r,c));
}
r = r + dr[i];
c = c + dc[i];
}
}
}
return false;
}
int main() {
int t;
while(scanf("%d",&t) != EOF) {
while(t--) {
memset(grid,0,sizeof(grid));
scanf("%d%d",&m,&n);
for(int i = 0; i < m; i++) {
scanf("%s",grid[i]);
}
scanf("%d%d%d%d%d",&k,&x1,&y1,&x2,&y2);
x1--;y1--;
x2--;y2--;
if( x1 == x2 && y1 == y2) {
printf("yesn");
continue;
}
bool flag = bfs();
if(flag) {
printf("yesn");
}
else {
printf("non");
}
}
}
return 0;
}
最后
以上就是洁净吐司为你收集整理的hdu1728 逃离迷宫( bfs + 标记转向次数)的全部内容,希望文章能够帮你解决hdu1728 逃离迷宫( bfs + 标记转向次数)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复