杭电1728bfs逃离迷宫java实现

Problem 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, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。
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
首先论对宽搜的认识,学习数据结构之前,一直看不懂什么是宽搜,当时遇到搜索题很是苦恼,只会用回溯法进行深搜,还是利用到了函数运行的机制(类似递归),第一次真正明白宽搜的运行机制是二叉树的遍历,有一种用队列的遍历方式(二叉树链接)才明白宽搜的运行机制,面对这题,深搜超时,可能有的大神优化能过。但是首先想到的应该是宽搜,核心点是转弯的次数。
1:刚开始我打算用boolean数组标记走过的位置,用class新类time表示点的转弯次数,后来错了。想了一想错的原因,右下右转两次,如果下右右只有一次但是晚走而没法走,所以这种想法是错的。
2:用数组标记当前点的最小转弯,如果新点,入队。若果比这个点的转弯次小于等于,也可以入队。这样就能保证最终找到最终答案,但是还是不过,超时。至于原因:楼梯模型(要克服楼梯的走楼梯而不直走的问题)
3:最终处理方案:使用优先队列,(java的需要自己百度学习一下),因为漫天都是C类的代码,教程,我根本不知道那个是优先队列。必须用优先队列优化。后来请教了学长帮我解决。优先队列让小节点先 入队。
wa了28次,第29次终于过了。
代码如下:

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
/*
 * bfs 标记节点,计入最小节点 优先队列优化
 */
public class 杭电1728bfs {
	static int a[][]= {{-1,0},{0,1},{1,0},{0,-1}};//左 上 右 下
	static boolean judgle=false;
	public static void main(String[] args) {	
	 Scanner sc=new Scanner(System.in);
	 int t=sc.nextInt(); 	//测试数据 
	 for(int t1=0;t1 q1=new PriorityQueue<>(timecomepare);
		e[y][x]=-1;
		q1.add(new zuobiao(x,y));		
		while(!q1.isEmpty())
		{
			zuobiao exa=q1.peek();//头坐标
			q1.poll();
			int x1=exa.x;int y1=exa.y;
			if(x1==x2&&y1==y2){if(exa.time<=k) {judgle=true;break;}}	
			else
			for(int i=0;i<4;i )
			{
	 if(x1 a[i][0]<0||x1 a[i][0]>n-1||y1 a[i][1]<0||y1 a[i][1]>m-1||c[y1 a[i][1]][x1 a[i][0]]==false){}//不能走或者走过	
				else 										
					{
					zuobiao zuo=new zuobiao(x1 a[i][0],y1 a[i][1],exa.time,exa.fangxiang);
					zuo.fangxiang=i;
					if(zuo.fangxiang!=exa.fangxiang) {zuo.time ;}
					if(e[y1 a[i][1]][x1 a[i][0]]>=zuo.time)//转头次数小于等于,入队
						{q1.add(zuo);e[y1 a[i][1]][x1 a[i][0]]=zuo.time;}																	
					else if(e[y1 a[i][1]][x1 a[i][0]]==0){//初始的没用过,入队
					q1.add(zuo);
					e[y1 a[i][1]][x1 a[i][0]]=zuo.time;			
					}		 
				} 
			}
			
		}
	}
	public static Comparator timecomepare =new Comparator()//实现comparator接口
			{
		 public int compare(zuobiao a1,zuobiao a2)
		 {
		 	 return (int)(a1.time-a2.time);
		 }
			};
}	
class zuobiao
{
	int x;
	int y;
	int time;
	int fangxiang;
	public zuobiao(int x,int y)
	{
		this.x=x;
		this.y=y;
		this.fangxiang=-1;
		this.time=-1;
	}
	public zuobiao(int x,int y,int time,int fangxiang)
	{
		this.x=x;
		this.y=y;
		this.time=time;
		this.fangxiang=fangxiang;
	}
	}

不知道有什么不妥或者不对的地方。请大神更正

你可能感兴趣的:(#,bfs)