|
|
|
@ -0,0 +1,136 @@
|
|
|
|
|
package org.alis.smallcc.algorithm;
|
|
|
|
|
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 回溯
|
|
|
|
|
* 洪水填充算法
|
|
|
|
|
* - 题例: 洪水会在一瞬间向四周填充
|
|
|
|
|
* - 从一个起始节点开始把附近与其连通的节点提取出或填充成不同颜色颜色,
|
|
|
|
|
* 直到封闭区域内的所有节点都被处理过为止,
|
|
|
|
|
* 是从一个区域中提取若干个连通的点与其他相邻区域区分开(或分别染成不同颜色)的经典算法。
|
|
|
|
|
*
|
|
|
|
|
* @author lc
|
|
|
|
|
* @date 2023/10/26 17:18
|
|
|
|
|
*/
|
|
|
|
|
public class Labyrinth {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final int[][] labyrinth = new int[][]{
|
|
|
|
|
{0, 1, 0, 0},
|
|
|
|
|
{0, 0, 0, 1},
|
|
|
|
|
{0, 1, 0, 1},
|
|
|
|
|
{0, 0, 0, 0}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
new Labyrinth().goLabyrinth();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 走迷宫
|
|
|
|
|
*/
|
|
|
|
|
public void goLabyrinth() {
|
|
|
|
|
// 迷宫有起点和终点
|
|
|
|
|
int start_x = 0;
|
|
|
|
|
int start_y = 0;
|
|
|
|
|
|
|
|
|
|
int end_x = 3;
|
|
|
|
|
int end_y = 3;
|
|
|
|
|
|
|
|
|
|
Set<Node> set = new HashSet<>();
|
|
|
|
|
go(new Node(end_x, end_y), new Node(start_x, start_y), set);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void go(Node end, Node current, Set<Node> set) {
|
|
|
|
|
// 如果是终点就直接返还
|
|
|
|
|
if (current.equals(end)) {
|
|
|
|
|
set.add(current);
|
|
|
|
|
print(set);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 此路不同
|
|
|
|
|
if (labyrinth[current.getX()][current.getY()] == 1) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 说明已经走过了
|
|
|
|
|
if (set.contains(current)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
set.add(current);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 往下
|
|
|
|
|
if (current.getX() + 1 < labyrinth.length) {
|
|
|
|
|
go(end, new Node(current.getX() + 1, current.getY()), set);
|
|
|
|
|
}
|
|
|
|
|
// 往下
|
|
|
|
|
if (current.getX() - 1 >= 0) {
|
|
|
|
|
go(end, new Node(current.getX() - 1, current.getY()), set);
|
|
|
|
|
}
|
|
|
|
|
// 往下
|
|
|
|
|
if (current.getY() + 1 < labyrinth[0].length) {
|
|
|
|
|
go(end, new Node(current.getX(), current.getY() + 1), set);
|
|
|
|
|
}
|
|
|
|
|
// 往下
|
|
|
|
|
if (current.getY() - 1 >= 0) {
|
|
|
|
|
go(end, new Node(current.getX(), current.getY() - 1), set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set.remove(current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void print(Set<Node> set) {
|
|
|
|
|
for (int i = 0; i < labyrinth.length; i++) {
|
|
|
|
|
for (int j = 0; j < labyrinth[i].length; j++) {
|
|
|
|
|
if (set.contains(new Node(i, j))) {
|
|
|
|
|
System.out.print("0");
|
|
|
|
|
} else {
|
|
|
|
|
System.out.print(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
System.out.println();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class Node {
|
|
|
|
|
private final int x;
|
|
|
|
|
private final int y;
|
|
|
|
|
|
|
|
|
|
public Node(int x, int y) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getX() {
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getY() {
|
|
|
|
|
return y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
|
if (this == o) return true;
|
|
|
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
|
|
|
Node node = (Node) o;
|
|
|
|
|
return x == node.x && y == node.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int hashCode() {
|
|
|
|
|
return Objects.hash(x, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|