蓝桥杯迷宫问题(Java实现)

因为最近有蓝桥杯考试,但我对于BFS还不是很熟悉。特意这里写文,记录我学习写蓝桥真题 迷宫问题的过程。

第一步将这么大又臭又长的字符串转为数组存储就吓到我了,原来只需要把字符连接起来,然后arr[i][j] = string.charAt(i*50+j) 就可以了

对于求解迷宫问题的最短路径,路径最短的情况下要求字典序最小,所以要BFS+放入顺序。

因为bfs无法用回溯维持一个path变量来显示所有路径,所以需要用string[][] 来保存每个位置的路径,或者将每个节点增加一个Node属性,表示到该节点的路径。这两种保存路径的方法有所差异。如果是String数组保存路径,那么上下左右的放入顺序要和优先级反过来,这是因为在同一层上一个坐标可以由“下右”和“右下”得到,而放在后面的会覆盖先访问的那个,所以相同的路径长度下(同一树层),我们要将优先级高的放后面,这样就优先级高的覆盖了优先级低的,最终显示的路径也是优先级高的。而节点属性存储路径就要优先级高的放前面,因为“下右”和“右下”是两个不同的节点,不是放在同个位置存储,没有覆盖的问题,先访问优先级高的,如果到达终点那一层,直接输出优先级高的路径就好了。

package forlanqiao19;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	public static void main(String[] args) {
		
		String string = "01010101001011001001010110010110100100001000101010"
		+"00001000100000101010010000100000001001100110100101"
		+"01111011010010001000001101001011100011000000010000"
		+"01000000001010100011010000101000001010101011001011"
		+"00011111000000101000010010100010100000101100000000"
		+"11001000110101000010101100011010011010101011110111"
		+"00011011010101001001001010000001000101001110000000"
		+"10100000101000100110101010111110011000010000111010"
		+"00111000001010100001100010000001000101001100001001"
		+"11000110100001110010001001010101010101010001101000"
		+"00010000100100000101001010101110100010101010000101"
		+"11100100101001001000010000010101010100100100010100"
		+"00000010000000101011001111010001100000101010100011"
		+"10101010011100001000011000010110011110110100001000"
		+"10101010100001101010100101000010100000111011101001"
		+"10000000101100010000101100101101001011100000000100"    //D -> L -> R -> U
		+"10101001000000010100100001000100000100011110101001"
		+"00101001010101101001010100011010101101110000110101"
		+"11001010000100001100000010100101000001000111000010"
		+"00001000110000110101101000000100101001001000011101"
		+"10100101000101000000001110110010110101101010100001"
		+"00101000010000110101010000100010001001000100010101"
		+"10100001000110010001000010101001010101011111010010"
		+"00000100101000000110010100101001000001000000000010"
		+"11010000001001110111001001000011101001011011101000"
		+"00000110100010001000100000001000011101000000110011"
		+"10101000101000100010001111100010101001010000001000"
		+"10000010100101001010110000000100101010001011101000"
		+"00111100001000010000000110111000000001000000001011"
		+"10000001100111010111010001000110111010101101111000";
		
		//将上面的一大串字符转为数组中存储,且数组为int型,仅存0 和 1两个值 
		int[][] moze= new int[30][50];
		for (int i = 0 ; i < 30 ; i++) {
			for(int j = 0 ; j < 50 ; j++) {
				moze[i][j] = string.charAt(i*50+j) - '0'; //
			}
		}
		//要实现bfs的话,需要向队列中不断加入数据,那么这个数据用什么来存储呢?我选择用一个节点来存储每个坐标以及到达该节点的路径。
		bfs(moze, 0, 0);
		
		
	}
	
	//bfs不是递归,无法回溯的。那么如何记录路径呢?我选择在节点中加入路径属性,每次向队列中加入新的节点时,都将该节点的路径初始化为前一个节点的路径+前一个节点到新节点的走法(U/L/R/D);这样的话,当访问到最后一个节点时,输出该节点的路径就是最终答案。
	//记录路径长度
	static int res;
	//记载路径
	static int[][] visited = new int[30][50];  //已经走过的就别走了,很关键,否则复杂度将大大增加。

	static void bfs(int[][] moze,int row ,int col) {
		Deque<Node> deque = new LinkedList<>();
		deque.offer(new Node(0,0));
		while (!deque.isEmpty()) {
			int len = deque.size();

			for(int i =  0 ; i < len; i ++) {
				Node node = deque.poll();
				visited[node.x][node.y] = 1;
				if (node.x == 29 && node.y == 49) {
					System.out.println(node.path);
					return;  //找到终点路径,直接退出。
				}
				if (node.x < 29 && moze[node.x+1][node.y] != 1 && visited[node.x+1][node.y] != 1) {  //这里的代码过于冗杂,建议写在方法体内
					Node newNode = new Node(node.x+1 , node.y);
					deque.offer(newNode);
					newNode.path = node.path + 'D';
					
				}
				if (node.y > 0 && moze[node.x][node.y-1] != 1 && visited[node.x][node.y-1] != 1) {
					Node newNode = new Node(node.x , node.y-1);
					deque.offer(newNode);
					newNode.path = node.path + 'L';

				}
				if(node.y < 49 && moze[node.x][node.y+1] != 1 && visited[node.x][node.y+1] != 1) {
					Node newNode = new Node(node.x , node.y+1);
					deque.offer(newNode);
					newNode.path = node.path + 'R';

				}
				if (node.x > 0 && moze[node.x-1][node.y] != 1 && visited[node.x-1][node.y] != 1) {
					Node newNode = new Node(node.x-1 , node.y);
					deque.offer(newNode);
					newNode.path = node.path + 'U';

				}
				
			} 
			res++;  //当每遍历完一层/向前后左右走一次 ,那么我的步数就要加1。
		}
		System.out.println(res);
		
	}
	
}
//要实现bfs的话,需要向队列中不断加入数据,那么这个数据用什么来存储呢?我选择用一个节点来存储每个坐标以及到达该节点的路径。
class Node{
	int x,y;
	String path = "";
	public Node() {
		// TODO Auto-generated constructor stub
	}
	Node(int x ,int y ){
		this.x = x;
		this.y = y;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值