定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
Input
一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径。
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
/**
* 迷宫路径-深度优先搜索
*
* @author 过路的守望
*
*/
public class Labyrinth {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int N = in.nextInt();
int M = in.nextInt();
/*
* 用双端队列打印时无需翻转顺序
*/
Deque<Node> deque = new LinkedList<>();
Node[][] data = new Node[N][M];
/*
* 四个搜索方向
*/
int[][] dir = { { 0, 1 }, { 1, 0 }};
/*
* 接收数据
*/
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
data[i][j] = new Node(in.nextInt(), i, j);
}
}
/*
* 添加起点
*/
deque.offerLast(data[0][0]);
data[0][0].setVisited(true);
Node cur = null;
int i = 0;
int j = 0;
/*
* 是否搜索到符合条件的下一个节点
*/
boolean find = false;
while (!deque.isEmpty()) {
cur = deque.peekLast();
i = cur.getX();
j = cur.getY();
find = false;
/*
* 横竖方向搜索
*/
for (int n = 0; n <2; n++) {
i = i + dir[n][0];
j = j + dir[n][1];
if (i >= 0 && i < N && j >= 0 && j < M
&& !data[i][j].isVisited()) {
/*
* 搜索到符合条件加入队列退出
*/
if (data[i][j].getValue() == 0) {
deque.offerLast(data[i][j]);
data[i][j].setVisited(true);
find = true;
break;
} else {
/*
* i,j下标恢复
*/
i = cur.getX();
j = cur.getY();
}
}
}
/*
* 搜索已完成,退出循环
*/
if (deque.peekLast() == data[N - 1][M - 1]) {
break;
}
/*
* 当前节点无法搜索到符合条件的下一个节点,从队列中删除,标记已访问过
*/
if (!find) {
cur = deque.pollLast();
cur.setVisited(true);
}
}
/*
* 打印路径
*/
for (Node node : deque) {
System.out.println("(" + node.getX() + "," + node.getY() + ")");
}
}
in.close();
}
}
/*
* 节点元素类
*/
class Node {
/*
* 节点值0或1
*/
private int value;
/*
* x,y节点所在位置下标
*/
private int x;
private int y;
/*
* 标记是否访问
*/
private boolean visited = false;
public Node(int value) {
super();
this.value = value;
}
public Node(int value, int x, int y) {
super();
this.value = value;
this.x = x;
this.y = y;
}
public int getValue() {
return value;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean isVisited() {
return visited;
}
public void setValue(int value) {
this.value = value;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
/**
* 迷宫路径 广度优先搜索
*
* @author 过路的守望
*
*/
public class Labyrinth {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int N = in.nextInt();
int M = in.nextInt();
int[][] map = new int[N][M];
int[][] visited = new int[N][M];
int[][] dir = { { 0, 1 }, { 1, 0 } };
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
map[i][j] = in.nextInt();
}
}
Queue<Node> queue = new LinkedList<Node>();
ArrayList<Node> list = new ArrayList<Node>();
int i = 0, j = 0;
Node cur = null;
Node start = new Node(0, 0);
queue.offer(start);
visited[0][0] = 1;
while (!queue.isEmpty()) {
cur = queue.poll();
list.add(cur);
for (int n = 0; n < 2; n++) {
i = cur.getX() + dir[n][0];
j = cur.getY() + dir[n][1];
if (i >= 0 && i < N && j >= 0 && j < M
&& visited[i][j] == 0 && map[i][j] == 0) {
Node next = new Node(i, j);
visited[i][j] = 1;
/*
* 设置前继节点坐标
*/
next.setPreX(cur.getX());
next.setPreY(cur.getY());
queue.offer(next);
}
}
}
/*
* 目的节点坐标
*/
int preX = list.get(list.size() - 1).getX();
int preY = list.get(list.size() - 1).getY();
/*
* 记录路径节点索引
*/
Stack<Integer> stack = new Stack<Integer>();
while (true) {
if (preX == 0 && preY == 0) {
break;
}
for (int k = 0; k < list.size(); k++) {
cur = list.get(k);
if (cur.getX() == preX && cur.getY() == preY) {
/*
* 设置前继节点坐标
*/
preX = cur.getPreX();
preY = cur.getPreY();
stack.push(k);
break;
}
}
}
stack.push(0);
while (!stack.isEmpty()) {
cur = list.get(stack.peek());
System.out
.println("(" + cur.getX() + "," + cur.getY() + ")");
stack.pop();
}
}
in.close();
}
}
class Node {
/*
* 节点坐标x,y.
*/
private int x;
private int y;
/*
* 前一个节点坐标
*/
private int preX;
private int preY;
public Node(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getPreX() {
return preX;
}
public int getPreY() {
return preY;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setPreX(int preX) {
this.preX = preX;
}
public void setPreY(int preY) {
this.preY = preY;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}