杭电1010java实现dfs

题目:
问题描述
小狗在一个古老的迷宫中发现了一块骨头,这让他着迷了很多。然而,当他拾起它时,迷宫开始动摇,小狗可能感觉到地面下沉。他意识到骨头是一个陷阱,他拼命地试图走出这个迷宫。

迷宫是一个大小为N的矩形。在迷宫中有一扇门。一开始,门被关闭,并在短时间内(不到1秒)在第T秒打开。因此小狗不得不在第T秒钟到达门口。每一秒,他都可以将一个街区移到上,下,左,右相邻街区之一。一旦他进入一个街区,这个街区的地面就会开始沉没,并在下一秒消失。他不能在一个街区停留超过一秒钟,也不能进入访问区块。这只可怜的小狗能生存吗?请帮助他。
输入
输入由多个测试用例组成。每个测试用例的第一行包含三个整数N,M和T(范围打出来后面会显示不出来)分别表示迷宫的大小和门打开的时间。接下来的N行给出迷宫布局,每行包含M个字符。一个字符是以下之一:
‘X’:小狗不能进入的一堵墙;
‘S’:小狗的起点;
‘D’:门;要么
‘。’:空白块。
输入以三个0结束。这个测试用例不被处理。
产量
对于每个测试案例,如果小狗能够存活,则在一行中打印“是”,否则打印“否”。
示例输入
4 4 5
S.X.
…X.
…XD

3 4 5
S.X.
…X.
… d
0 0 0
示例输出
NO
YES
这是我第一个做的深搜题,讲一下我做这题的错误和进步过程
1:我最初只使用普通的搜索题,利用递归回溯可以找到结果。但是超时
2:看了网上的分析之后,才明白要剪枝,就是把不可能的情况减掉,我看了别人的剪枝,才知道原来两个点的奇偶性和走的步数的奇偶密切相关,即:偶数点到偶数点(坐标xy之和)需要走偶数次,奇数到奇数也要走偶数次。说明两点%2的结果如果相同就会走偶数次。相反则走奇数次,经过优化后if((x1 y1 x2 y2)%2 t%2==1) {return;}除了主要的这个,还想到了步数能不能到达,步数会不会超过所有路的问题。
3:发现还是超时,后来才想明白需要走一步剪枝规范去掉没用的,这样减少的次数是不仅仅初始的那个状态。这样优化后理论上可以ac
4:但是我依然超时,做了很多尝试,发现我的dfs函数的参数过多,我把他写在外面静态区域,就成功ac了。可以看代码
代码如下:(被注释部分代码就是超时而没法过的最初形式)

import java.util.Scanner;
public class 杭电1010 {
	static int d[][]= {{-1,0},{0,-1},{1,0},{0,1}};//上左下右
	static boolean judgle=false;
	static int n,m,t,x2,y2;//行列 时间 们的位置
	public static void main(String[] args) {	
	 Scanner sc=new Scanner(System.in);	 
	 while(sc.hasNext())
	 {
//	 	 int n=sc.nextInt();//行数
//	 	 int m=sc.nextInt();//列数
//	 	 int t=sc.nextInt();//门打开的时间
	 	 n=sc.nextInt();//行数
	 	 m=sc.nextInt();//列数
	 	 t=sc.nextInt();//门打开的时间
	 	 sc.nextLine();
	 	 if(n==0&&m==0&&t==0)break;
	 	 char a[][]=new char[n][m];
	 	 boolean b[][]=new boolean[n][m];//判断是否有障碍
	 	 boolean c[][]=new boolean[n][m];//走过记录
	 	 int x1=0,y1=0; 	 
	 	 for(int i=0;i=m*n) {judgle=false;}//时间超了 	 	 
	 	 else {
	 	 dfs(b,c,x1,y1);}
	 	 if(judgle) {System.out.println("YES");judgle=false;}
	 	 else
	 		 {System.out.println("NO");}
	 	 
	 }	 	 
	}
	//private static void dfs( boolean[][] b,boolean c[][], int x1, int y1, int x2, int y2,int m,int n,int t) {
	private static void dfs( boolean b[][], boolean c[][], int x1, int y1) {	
		if(t==0) {if(x1==x2&&y1==y2)judgle=true;return;}	//到达终点
		else if((x1 y1 x2 y2)%2 t%2==1) {return;}	//奇偶剪
		else if(t=n||y1 d[i][0]>=m){continue;}//不越界
				else
				{
					if(!b[x1 d[i][1]][y1 d[i][0]]&&!c[x1 d[i][1]][y1 d[i][0]]) //you障碍				
					{					
						x=x d[i][1];y=y d[i][0];t--;c[x][y]=true;	
						if(t==0&&x==x2&&y==y2) {judgle=true;break;}	//找到结果结束											
						dfs(b,c,x,y);	
						c[x][y]=false;t ;					
					}				
				}								
			}
		}	
	}
}

不知道还有什么优化的方法,希望大佬能过指出!

你可能感兴趣的:(#,dfs,杭电,dfs,java,剪枝算法)