JAVA算法:解救小哈(JAVA版)

JAVA算法:解救小哈(JAVA版)

有一天,小哈一个人去玩迷宫。但是方向感不好的小哈很快就迷路了。小哼得知后便去解救无助的小哈。此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈。那么,问题来了...

迷宫地图表示:0—表示通路;1—表示障碍

 第一组用例:

输入迷宫坐标
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
 

小哈的位置:(3,2)

输出

7

第二组用例:

输入迷宫坐标
1 1 1 
0 1 0 
0 1 0 

输出

No Way!
 


算法分析

迷宫表示

0010
0000
0010
0100
0001

方向定义

1,11,21,3
2,12,22,3
3,13,23,3

设定一个坐标系的话,如下方格所示:

 (X-1,Y) 
(X,Y-1)(X,Y)(X,Y+1)
 (X+1,Y) 

 也就是说纵向用X轴表示,横向用Y轴表示。这个坐标轴非常重要,因为我们以此构建方向数组:

    	//搜索顺序:右,下,左,上
    	int[][] next=new int[][] {
    		{0,1},//向右走
    		{1,0},//向下走
    		{0,-1},//向左走
    		{-1,0} //向上走
    	};

 


算法设计

package com.bean.algorithm.dfsbfs;

import java.util.LinkedList;

public class HelpXiaoHa {
	
	/**
     * 定义迷宫数组
     */
	
    private int maxY = 4;
    private int maxX = 5;
    int min=Integer.MAX_VALUE;
    int endX=3;
    int endY=2;
    int[][] maze=new int[maxX][maxY];
    int[][] mark=new int[maxX][maxY];
    LinkedList<Integer> map=new LinkedList<Integer>();
    
    /*
	 * 初始化迷宫
	 * */
	public void initMaze() {
		
		this.maze = new int[][] {
			{ 0, 0, 1, 0 },
			{ 0, 0, 0, 0 },
			{ 0, 0, 1, 0 },
			{ 0, 1, 0, 0 },
			{ 0, 0, 0, 1 }
	    };
	    
	    
	    this.mark=new int[maxX][maxY];
	    this.mark[0][0]=1;
	    
	    //输出迷宫地图,其中: * 代表障碍物;_代表可以通过
	    for(int x=0;x<maxX;x++) {
	    	for(int y=0;y<maxY;y++) {
	    		if(x==endX && y==endY) {
	    			System.out.print("! ");
	    		}else if(this.maze[x][y]==1) {
	    			System.out.print("* ");
	    		}else {
	    			System.out.print("_ ");
	    		}
	    	}
	    	System.out.println();
	    }
	    System.out.println();
	    
	}
 
    public void dfs(int startX,int startY,int step) {
    	//搜索顺序:右,下,左,上
    	int[][] next=new int[][] {
    		{0,1},//向右走
    		{1,0},//向下走
    		{0,-1},//向左走
    		{-1,0} //向上走
    	};
    	
    	
    	int nextX;
    	int nextY;
    	int posible;
    	//判断是否达到小哈的位置
    	if(startX==endX && startY==endY) {
    		//判断是否用了最少的步数steps
    		if(step<min) {
    			min=step;
    		}
    		
    		for(int i=map.size()-1;i>=0;i-=2) {
    			nextX=map.get(i);
    			nextY=map.get(i-1);
    			System.out.print("["+nextX+","+nextY+"]");
    			if(i!=1) {
    				System.out.print("->");
    			}
    		}
    		System.out.println();
        	return;
    	}
    	
    	for(posible=0;posible<next.length;posible++) {
    		//顺序:右,下,左,上
    		//计算下一个点的坐标
    		nextX=startX+next[posible][0];
    		nextY=startY+next[posible][1];
    		//判断是否越界
    		if(nextX<0||nextX>=maxX||nextY<0||nextY>=maxY) {
    			continue;
    		}
    		
    		if(maze[nextX][nextY]==0 && mark[nextX][nextY]==0) {
    			map.push(nextX);
    			map.push(nextY);
    			mark[nextX][nextY]=1;
    			dfs(nextX,nextY,step+1); //递归调用,移动到下一格子
    			mark[nextX][nextY]=0;
    			map.pop();
    			map.pop();
    			
    		}
    	}
    	
    }
    
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HelpXiaoHa help=new HelpXiaoHa();
		
		int startX=0;
		int startY=0;
		
		long startTime=System.currentTimeMillis();
		
		help.initMaze();
		help.dfs(startX, startY, 0);
		if(help.min<Integer.MAX_VALUE) {
			System.out.println("At least "+help.min+" steps.");
		}else {
			System.out.println("No Way!");
		}
		
		long endTime=System.currentTimeMillis();
	    System.out.println("Elapsed time: "+(endTime-startTime)+" ms.");
	}

}

 

程序运行结果:

 

_ _ * _ 
_ _ _ _ 
_ _ * _ 
_ * ! _ 
_ _ _ * 

[0,1]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[0,1]->[1,1]->[2,1]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[0,1]->[1,1]->[1,0]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[1,0]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[1,0]->[1,1]->[2,1]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[1,0]->[2,0]->[2,1]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[1,0]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
At least 7 steps.
Elapsed time: 4 ms.

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值