杭电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 Main {
    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())
           {
               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<n;i++)//赋值
               {
                   String exa=sc.nextLine();                   
                   a[i]=exa.toCharArray();
               }
               for(int i=0;i<n;i++)//赋值
               {
                   for(int j=0;j<m;j++)//赋值
                   {
                       if(a[i][j]=='X') {b[i][j]=true;}//有障碍
                       else if(a[i][j]=='S') {x1=i;y1=j;}//起点
                       else if(a[i][j]=='D') {x2=i;y2=j;}//结束点
                   }
               }
               c[x1][y1]=true;
              // if((x1+y1+x2+y2)%2+t%2==1) {judgle=false;}               
                if(t>=m*n) {judgle=false;}//时间超了
             //  else if(t<Math.abs(y1-y2)+Math.abs(x2-x1)) {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<Math.abs(y1-y2)+Math.abs(x2-x1)) {return;}
        else
        {
            for(int i=0;i<4;i++)
            {
                int x=x1,y=y1;
                if(x1+d[i][1]<0||y1+d[i][0]<0||x1+d[i][1]>=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++;                    
                    }                
                }                                
            }
        }    
    }
}
目录
相关文章
【Java每日一题,dfs】矩阵查找字符串
【Java每日一题,dfs】矩阵查找字符串
|
8月前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
60 4
|
8月前
|
Java
杭电 OJ 1010-1019 Java解法(未更新完毕)
杭电 OJ 1010-1019 Java解法(未更新完毕)
36 1
|
8月前
|
Java
01背包介绍与N皇后(dfs,考验代码能力JAVA)
01背包介绍与N皇后(dfs,考验代码能力JAVA)
|
8月前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
|
8月前
|
Java
杭电acm1201 18岁生日 Java解法 时间类
杭电acm1201 18岁生日 Java解法 时间类
39 0
|
8月前
|
算法 Java
杭电 OJ 1000-1009 Java解法
杭电 OJ 1000-1009 Java解法
33 0
|
8月前
|
Java
杭电acm2018 母牛的故事 Java解法 经典递归
杭电acm2018 母牛的故事 Java解法 经典递归
46 0
|
8月前
|
Java BI
杭电acm1013 Digital Roots 数字根 Java解法 高精度
杭电acm1013 Digital Roots 数字根 Java解法 高精度
40 0
|
9月前
|
数据采集 算法 Java
DFS(深度搜索)无向图遍历(JAVA手把手深入解析)
DFS(深度搜索)无向图遍历(JAVA手把手深入解析)
84 0

热门文章

最新文章