您的位置:首页 > 其它

HDU 1728 逃离迷宫

2016-10-08 17:37 281 查看
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对应行。

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

//开始此题用dfs做的,能对,但超时
//用广搜
//但不是一般的广搜,而是结合了深搜思想
//如果,还是用普通广搜,结果仍有可能超时
//既然是求最小转弯数,那么此题的重点不同于以前求最短路径,而是去求最小转弯数,路程再远也没关系
//求出搜索到终点前每点的最小转弯数
//于是,一个点广搜不是上下左右四个点,而是上下左右四个方向能搜索的所有点
//沿一个方向搜索时,会遇到碰到已经搜到的点的情况,不用管,接着走,直到不能走
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node{
int x;
int y;
int turn;//到此点最小的转弯次数
};
struct node start,end;//起点与终点
struct node queue[10001];
int head=0;
int tail=0;
int next[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int m,n;
int k;
char map[101][101];
int book[101][101];

int bfs()
{
start.turn=-1;//起点的turn赋值为-1
book[start.x][start.y]=1;
queue[tail].x=start.x;
queue[tail].y=start.y;
queue[tail].turn=start.turn;
tail++;
while(head<tail){
if(queue[head].x==end.x&&queue[head].y==end.y&&queue[head].turn<=k)
return 1;
int xnext;
int ynext;
for(int i=0;i<4;i++){
xnext=queue[head].x+next[i][0];
ynext=queue[head].y+next[i][1];
while(xnext>=1&&xnext<=m&&ynext>=1&&ynext<=n&&map[xnext][ynext]=='.'){
if(book[xnext][ynext]==0){
book[xnext][ynext]=1;
queue[tail].x=xnext;
queue[tail].y=ynext;
queue[tail].turn=queue[head].turn+1;
tail++;
}
xnext=xnext+next[i][0];
ynext=ynext+next[i][1];

}
}
head++;
}
return 0;
}
int main()
{
int number;
scanf("%d",&number);
for(int i=1;i<=number;i++){
scanf("%d%d",&m,&n);
for(int j=1;j<=m;j++)
scanf("%s",map[j]+1);
scanf("%d%d%d%d%d",&k,&start.y,&start.x,&end.y,&end.x);
for(int t=0;t<101;t++)
memset(book[t],0,sizeof(book[t]));
head=0;
tail=0;
int flag=bfs();
if(flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
}


//dfs没过的
#include <stdio.h>
#include <stdlib.h>
struct node{
int x;
int y;
};
struct node start,end;
int m,n;
int k;
char map[101][101];
int book[101][101];
int flag;
int next[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//去:上左下右
int to[4]={1,2,3,4};//代表四个方向,上左下右
void dfs(int x,int y,int towards,int occur)
{
if(x==end.x&&y==end.y){
if(occur<=k)
flag=1;
return;
}
int xnext,ynext;
for(int i=0;i<4;i++){
xnext=x+next[i][0];
ynext=y+next[i][1];
if(xnext>=1&&xnext<=m&&ynext>=1&&ynext<=n&&book[xnext][ynext]==0&&map[xnext][ynext]=='.'){
book[xnext][ynext]=1;
if(x==start.x&&y==start.y)
dfs(xnext,ynext,to[i],0);
else
dfs(xnext,ynext,to[i],occur+((int)fabs(towards-to[i]))%2);
book[xnext][ynext]=0;
}
}
return;
}
int main()
{
int number;
scanf("%d",&number);
//getchar();
for(int i=1;i<=number;i++){
flag=0;
scanf("%d%d",&m,&n);
//getchar();
for(int j=1;j<=m;j++)
scanf("%s",map[j]+1);
scanf("%d%d%d%d%d",&k,&start.y,&start.x,&end.y,&end.x);
//for(int t=0;t<101;t++)
//memset(book[t],0,sizeof(book[t]));
book[start.x][start.y]=1;
dfs(start.x,start.y,0,0);
if(flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: