逃离迷宫

给定一个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 ≤ x1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能转的弯数,(x 1, y 1), (x 2, y2)表示两个位置,其中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
#include<queue>
#include<cstdio>
#include<stdio.h>
#include<string.h> 
using namespace std;

char maze[101][101];//地图面积 
int vis[105][105]; //标记是否已经访问 
int n,m;	//分别代表行数和列数 
int k,x1,y1,x2,y2;//最大转弯次数,起点,终点 
int t;//代表有多少组
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; //所有方向
int flag; //标记是否完成 

struct node{
	int x,y,k;
};

void bfs(){
	node now,next,bri;
	//将起始坐标赋值给now 
	now.x = x1;
	now.y = y1;
	now.k = -1; //起初的方向不算,故从-1开始 
	vis[x1][y1]=1; //将起始坐标标记为已访问 
	queue<node> que;
	que.push(now); //压入队列 
	while(que.size()){
		now = que.front(); que.pop(); //将队列中的第一个给now,并弹出 
		if(now.x==x2&&now.y==y2&&now.k<=k){
			//如果now为终点坐标并且转弯数小于最大转弯数 flag设为1 
			flag = 1;
		}
		
		for(int i = 0;i<4;i++){ //四个方向进行遍历 
			next.x = now.x+dir[i][0];
			next.y = now.y+dir[i][1];
			while(0<=next.x&&next.x<n&&0<=next.y&&next.y<m&&maze[next.x][next.y]=='.'){
				/*
				*思路: 一条路到底,一直走一个方向下去,并把该方向上可以访问的点压入队列
				*		 然后每个方向都是如此 
				* 		例 (x1,y1)=(0,0) -->a  (x2,y2)=(0,2) -->b 
				*	step1	a_-1 ._0 ._0 *_  *_ 
				*			*_   ._  *_  *_  ._
				*			b_   ._  ._  ._  ._
				*			._   ._  ._  ._  ._
				*			*_   ._  ._  ._  ._
				*			
				*	step2	a_-1 ._0 ._0 *_  *_ 
				*			*_   ._1 *_  *_  ._
				*			b_   ._1 ._  ._  ._
				*			._   ._1 ._  ._  ._
				*			*_   ._1 ._  ._  ._
				*			
				*	step3	a_-1 ._0 ._0 *_  *_ 
				*			*_   ._1 *_  *_  ._3
				*			b_2  ._1 ._2 ._2 ._2
				*			._2  ._1 ._2 ._2 ._2
				*			*_   ._1 ._2 ._2 ._2
				*/
				if(vis[next.x][next.y]==0){ //该点还未被访问 
					next.k = now.k+1;
					vis[next.x][next.y] = 1; //标记该点为已访问 
					que.push(next);
				}
				bri.x = next.x + dir[i][0];
				bri.y = next.y + dir[i][1];
				next = bri;
			}
		}
	}
	//return;
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		for(int i = 0;i<n;i++){
			scanf("%s",&maze[i]);
		}
		memset(vis,0,sizeof(vis));
		scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
		x1-=1;y1-=1;x2-=1;y2-=1;
		flag = 0;
		bfs();
		if(flag)
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}

如果用dfs,结果时间超时了,不过值得看看

/*
* 用dfs做 结果为时间超时了 
*/

#include<stdio.h>
int m,n;//分别代表行数 列数
int t; //代表有几组测试数据
int direction; //代表当前方向
int dir[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}}; //所有方向
int count; //记录转弯次数
int maxcount; //最大能转弯的次数
int x1,y1,x2,y2; //代表起点终点的坐标
char maze[100][101]; //地图 
int flag; //标记是否已经完成 

void dfs(int x,int y){//x对应是列,y对应的是行 
	/*
	*有几种情况
	*	1.转弯次数已经超过了最大能转弯的次数,flag默认值为0 
	*	2. 已经找到可以到达的路径flag=1 
	*方向的记录
	*解:将走的坐标以代号了记录 
	*		(0,0) --> 0
	*		(0,1) --> 1 
	*		(1,0) --> 2
	*		(0,-1)--> 3 
	*		(-1,0)--> 4 
	*/
	if(count>maxcount+1)//第一种情况 
		return;
	if(flag)
		return;
	if(x==x2&&y==y2){//第二种情况 
		if(count<=maxcount+1)
			flag=1;
		return;
	} 
	
	for(int i=1;i<5;i++){
		int newx = x+dir[i][0];
		int newy = y+dir[i][1];
	
		int olddirection = direction;
		if(0<=newx&&newx<n&&0<=newy&&newy<m&&maze[newy][newx]=='.'){
			//首先该点必须在地图里面,并且是路即为'.'
			/*
			*思路: 从一个位置出发,往能走的地方一直走,直到走不了了,
					然后退一步,转弯,继续上述过程 
			*/
			if(direction!=i)
			//如果direction与当前方向i不一样,代表转向了 
				count++;
			direction=i; //再将新的方向给direction,无论方向变没变 
			dfs(newx,newy);
			if(olddirection!=i)
			 	count--;
			direction=olddirection;
			
		}
	}
} 
int main(){
	scanf("%d",&t); //输入有多少组测试样例
	while(t--){
		//初始化 
		count=0;//因为第一次的方向不算转向,所有从-1开始 
		direction = 0; //让起始位置开始走的方向一定算进去了
		flag =0; // flag开始就是未完成状态
		 
		scanf("%d%d",&m,&n);//m对应行数,n对应列数 
		for(int i = 0;i<m;i++){
			scanf("%s",&maze[i]);
		}
		scanf("%d%d%d%d%d",&maxcount,&x1,&y1,&x2,&y2);
		//x1,x2对应列,y1,y2对应行 
		//因为它坐标第一行是1,在电脑里是0 
		x1-=1;y1-=1;x2-=1;y2-=1;
		dfs(x1,y1);
		if(flag)
			printf("yes\n");
		else
			printf("no\n"); 
	}
	return 0; 
}