HDOJ-ACM1010(JAVA) 奇偶剪枝法 迷宫搜索

转载声明:原文转自:http://www.cnblogs.com/xiezie/p/5568822.html

 

第一次遇到迷宫搜索,给我的感觉是十分惊喜的:搞懂这个的话,感觉自己又掌握了一项技能~

个人感觉,角色扮演类的游戏,起码都可以在迷宫搜索上找到影子。

奇偶剪枝这个算法感觉十分开阔的视野~这样去描述这个具体问题实在太形象生动了~

总而言之,十分有趣。

仔细的人会发现  每当设计到移动,我们必须想到上下左右,这也让我们看到这类算法的思路。

在学习迷宫搜索当中,我发现:这个搜索算法是先分析 找到结果时的情形,然后再将通路换为障碍,经过上下左右后,再换回通路。(这是递归写法该有的一种套路吗?才疏学浅,不敢妄言)

 

另外,迷宫搜索类的题目不仅涉及到 回溯法,还让人好奇迷宫生成的算法~

接下来,应该研究下 迷宫生成算法和迷宫搜索算法中提及的 深度、广度搜索

 

不得不借鉴他人的成果:

下面是剪枝的简单理论,一看就懂:

                          把map看作

                             0 1 0 1 0 1
                             1 0 1 0 1 0
                             0 1 0 1 0 1
                             1 0 1 0 1 0
                             0 1 0 1 0 1

                       从 0->1 需要奇数步

                       从 0->0 需要偶数步

以下是JAVA实现代码:

import java.util.*;
import java.io.*;

public class Main{

    public static void main(String[] arg){
        Scanner scan = new Scanner(new BufferedInputStream(System.in));
        int n,m,t;
        while((n=scan.nextInt())!=0&&(m=scan.nextInt())!=0&&(t=scan.nextInt())!=0){
            ok = false;
            int x = 0,y = 0;
            int targetX = 0,targetY = 0;
            char[][] map = new char[n][m];
            for(int i = 0 ; i != n ; i ++ ){
                String row = scan.next();
                char[] c = row.toCharArray();
                for(int j = 0 ; j != m ; j ++ ){
                    map[i][j]=c[j];
                    if(c[j]=='.'){
                        continue;
                    }
                    if(c[j]=='X'){
                        continue;
                    }
                    if(c[j]=='S'){
                        x = i;
                        y = j;
                        continue;
                    }
                    if(c[j]=='D'){
                        targetX = i;
                        targetY = j;
                    }
                }
            }
            //剪枝
            if((targetX+targetY)%2==(x+y)%2){//相同
                if(t%2==1){
                    t=-1;
                }
            }else{
                if(t%2==0){//相异
                    t=-1;
                }
            }
            findPath(map,x,y,t,targetX,targetY);
            if(t==-1){
                System.out.println("NO");
                continue;
            }
            if(ok){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
        }
        scan.close();
    }

    static boolean ok = false;

    static void findPath(char[][] map,int i , int j,int t,int targetX,int targetY){
        if(ok||t==-1){
            return;
        }
        if(t==0&&(map[i][j]=='D'||i==targetX&&j==targetY)){
            ok = true;
            return;
        }
        map[i][j] = 'X';
        //
        if(j - 1!=-1&& map[i][j-1]!='X'){
            findPath(map,i,j-1,t-1,targetX,targetY);
        }
        //
        if(j + 1!=map[0].length&&map[i][j + 1]!='X' ){
            findPath(map,i,j+1,t-1,targetX,targetY);
        }
        //
        if(i - 1!=-1&&map[i-1][j]!='X'){
            findPath(map,i-1,j,t-1,targetX,targetY);
        }
        //
        if(i + 1!=map.length&&map[i+1][j ]!='X' ){
            findPath(map,i+1,j,t-1,targetX,targetY);
        }
        map[i][j] = '.';
    }

}

 

posted on 2016-06-08 00:58  xiezie  阅读(732)  评论(0编辑  收藏  举报

导航