java迷宫问题 华为_剑指Offer——回溯算法解迷宫问题(java版)

剑指Offer——回溯算法解迷宫问题(java版)

以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计程序,对任意设定的迷宫,求出从入口到出口的所有通路。

下面我们来详细讲一下迷宫问题的回溯算法。

(入口) 0 0 1 0 0 0 1 0

0 0 1 0 0 0 1 0

0 0 1 0 1 1 0 1

0 1 1 1 0 0 1 0

0 0 0 1 0 0 0 0

0 1 0 0 0 1 0 1

0 1 1 1 1 0 0 1

1 1 0 0 0 1 0 1

1 1 0 0 0 0 0 0(出口)

该图是一个迷宫的图。1代表是墙不能走,0是可以走的路线。只能往上下左右走,直到从左上角到右下角出口。

做法是用一个二维数组来定义迷宫的初始状态,然后从左上角开始,不停的去试探所有可行的路线,碰到1就结束本次路径,然后探索其他的方向,当然我们要标记一下已经走的路线,不能反复的在两个可行的格子之间来回走。直到走到出口为止,算找到了一个正确路径。

程序如下,具体做法看注释即可。

package cn.edu.ujn.demo;

/**

*@author SHQ

*

* 迷宫问题求解

*

* 思路

* 递归+回溯

*

* 按照右-->左-->下-->上的顺序寻路,已走过的路径用5标志

*

*

*/

public class MiGong { public static void main(String[] args) { int maxRow,maxLine,p; Scanner in = new Scanner(System.in); Pattern pattern = Pattern.compile("[ ]+"); String s = in.nextLine(); String [] str = pattern.split(s); // 获取行 maxRow = Integer.parseInt(str[0]); // 获取列 maxLine = Integer.parseInt(str[1]); // 获取能量值

// p = Integer.parseInt(str[2]); int [][] array = new int [maxRow][maxLine]; for(int i = 0; i < maxRow; i++){ for(int j = 0; j < maxLine; j++){ array[i][j] = in.nextInt(); } } Long start = System.currentTimeMillis(); new MiGong().check(0, 0, array, maxRow, maxLine); Long end = System.currentTimeMillis(); System.out.println("耗时:" + (end-start) + "ms"); } /** * 制定走的规则 *@param i *@param j *@param array *@param maxRow *@param maxLine */ private void check(int i, int j, int[][] array, int maxRow, int maxLine) { // 递归出口(如果到达右下角出口) if (i == maxRow - 1 && j == maxLine - 1) { print(array, maxRow, maxLine); return; } //向右走 if (canMove(i, j, i, j + 1, array, maxRow, maxLine)) { // 已走过的点置标志位5 array[i][j] = 5; // 从下一个点继续寻路 check(i, j + 1, array, maxRow, maxLine); // 均不可行,则恢复现场 array[i][j] = 0; } //向左走 if (canMove(i, j, i, j - 1, array, maxRow, maxLine)) { // 标记为已走 array[i][j] = 5; // 递归调用 check(i, j - 1, array, maxRow, maxLine); array[i][j] = 0; } //向下走 if (canMove(i, j, i + 1, j, array, maxRow, maxLine)) { array[i][j] = 5; check(i + 1, j, array, maxRow, maxLine); array[i][j] = 0; } //向上走 if (canMove(i, j, i - 1, j, array, maxRow, maxLine)) { array[i][j] = 5; check(i - 1, j, array,maxRow, maxLine); array[i][j] = 0; } } /** * 判断[i,j]-->[targetI,targetJ]是否可行 *@param i *@param j *@param targetI *@param targetJ *@param array *@param maxRow *@param maxLine *@return boolean 可否通过 */ private boolean canMove(int i, int j, int targetI, int targetJ, int[][] array, int maxRow, int maxLine) {

// System.out.println("从第" + (i + 1) + "行第" + (j + 1) + "列,走到第" + (targetI + 1) + "行第" + (targetJ + 1) + "列"); if (targetI < 0 || targetJ < 0 || targetI >= maxRow || targetJ >= maxLine) {

// System.out.println("到达最左边或最右边,失败了"); return false; } if (array[targetI][targetJ] == 1) {

// System.out.println("目标是墙,失败了"); return false; } //避免在两个空格间来回走 if (array[targetI][targetJ] == 5) {

// System.out.println("来回走,失败了"); return false; } return true; } /** * 打印可行路径 *@param array *@param maxRow *@param maxLine */ private void print(int [][] array, int maxRow, int maxLine) { System.out.println("得到一个解:"); for (int i = 0; i < maxRow; i++) { for (int j = 0; j < maxLine; j++) { System.out.print(array[i][j] + " "); } System.out.println(); } }

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

计算结果如下:

db55f9ea97d67d89ab1541fe97e6ece7.png

f762c6b8294f353cf5ad1f47b2e89644.png

6776a88c8d7e68380fa97ed19a6e6e5d.png

d4dab2f213d7ce2d773177cafcd873e1.png

美文美图

83b958fdb770fe1a7218f54d726d44d5.png

c17609b3db942e573515315900000b81.png

e2925a6a0f48aa86112cdf87b9ed2a16.png

文章来源: shq5785.blog.csdn.net,作者:No Silver Bullet,版权归原作者所有,如需转载,请联系作者。

原文链接:shq5785.blog.csdn.net/article/details/52599850

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方阵形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值