hdu-1728(贪心&&bfs的灵活运用吧)

链接

[https://vjudge.net/contest/256476#problem/D]

题意

 给定一个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是就尽快能的往同一方向走这就尽可能地减少转弯
但是代码实现的时候有个bug.我后面也是看了别人的才知道自己的错
[https://www.cnblogs.com/qiufeihai/archive/2012/08/27/2659159.html]
讲的很清楚了。需要解释一下关键代码

	str ok;
	    ok.curk=tem.curk+1;
		for(int i=0;i<4;i++){
			 ok.r=tem.r+d[i][0],ok.c=tem.c+d[i][1];
			while(ok.r>=1&&ok.r<=n&&ok.c>=1&&ok.c<=m&&ma[ok.r][ok.c]=='.')
		    {
		    	//即使其他方向的走过了这里,但是从另一个方向走的时候是可以经过这个位置的 
		    	if(!vis[ok.r][ok.c])
		    	{//没检测过的点就检测 
		    		q.push(ok);
		    	   vis[ok.r][ok.c]=1;
				}
				//即使检测过了我也可以经过这个点往其他方向搜索 
		    	ok.r+=d[i][0];
		    	ok.c+=d[i][1];
			}
		}

完整代码

#include<iostream>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=110;
char ma[N][N];
bool vis[N][N];
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
//上下左右 
int x1,x2,y1,y2,k,n,m;
bool flag;
struct str{
	int r,c,curk;
};
void bfs(){
	str tem;
	memset(vis,0,sizeof(vis));
	tem.r=x1,tem.c=y1,tem.curk=-1;
	vis[x1][y1]=1;
	queue<str> q;
	q.push(tem);
	while(!q.empty()){
		tem=q.front();
		q.pop();
		if(tem.r==x2&&tem.c==y2&&tem.curk<=k){
			flag=1; break;
		}
	    str ok;
	    ok.curk=tem.curk+1;
		for(int i=0;i<4;i++){
			 ok.r=tem.r+d[i][0],ok.c=tem.c+d[i][1];
			while(ok.r>=1&&ok.r<=n&&ok.c>=1&&ok.c<=m&&ma[ok.r][ok.c]=='.')
		    {
		    	//即使其他方向的走过了这里,但是从另一个方向走的时候是可以经过这个位置的 
		    	if(!vis[ok.r][ok.c])
		    	{//没检测过的点就检测 
		    		q.push(ok);
		    	   vis[ok.r][ok.c]=1;
				}
				//即使检测过了我也可以经过这个点往其他方向搜索 
		    	ok.r+=d[i][0];
		    	ok.c+=d[i][1];
			}
		}
	}
}
int main(){
	int t;
	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--){
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>ma[i][j];
		
		scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
		flag=0;
		bfs();
		if(flag)
		printf("yes\n");
		else printf("no\n");
	}
	return 0;
}
posted @ 2019-04-02 21:08  ChunhaoMo  阅读(173)  评论(0编辑  收藏  举报