深度和广度搜索
1. 全排列
输入n,输出1-n所有的非重复全排列
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
queue = new int[n];
mark = new int[n];
dfs(0);
}
private static int n;
private static int[] queue;
private static int[] mark;
public static void dfs(int step) {
if(step == n) {
for(int i = 0;i<n;i++) {
System.out.print(queue[i]);
}
System.out.println();
return;
}
for(int i = 0;i<n;i++) {
if(mark[i] == 0) {
mark[i] = 1;
queue[step] = i+1;
dfs(step+1);
mark[i] = 0;
}
}
}
}
2. 在□□□+□□□=□□□中填入1-9,输出可能的填法
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
queue = new int[9];
mark = new int[9];
dfs(0);
}
private static int[] queue;
private static int[] mark;
public static void dfs(int step) {
if(step == 9) {
if(queue[0]*100+queue[1]*10+queue[2]+
queue[3]*100+queue[4]*10+queue[5]==
queue[6]*100+queue[7]*10+queue[8]) {
for(int i = 0;i<9;i++) {
System.out.print(queue[i]);
if(i == 2) {
System.out.print("+");
}
if(i ==5) {
System.out.print("=");
}
}
System.out.println();
}
return;
}
for(int i = 0;i<9;i++) {
if(mark[i] == 0) {
mark[i] = 1;
queue[step] = i+1;
dfs(step+1);
mark[i] = 0;
}
}
}
}
3. 玩迷宫
迷宫由n行和m列的单元格组成,每个单元格要么是空地,要么是障碍物。找到一条从起点到终点的最短路径。
用一个二源数组来存储这个迷宫,起点(0,0)终点(p,q)。
输入 n m和迷宫,1表示障碍物
深度Depth-first search
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
maze = new int[n][m];
mark = new boolean[n][m];
currentPath = new int[n*m][2];
minPath = new int[n*m][2];
location = new int[2][2];
for(int i = 0;i<n;i++)
for(int j = 0;j<m;j++) {
maze[i][j] = in.nextInt();
}
location[0][0] = in.nextInt(); //当前点
location[0][1] = in.nextInt();
location[1][0] = in.nextInt(); //终点
location[1][1] = in.nextInt();
mark[location[0][0]][location[0][1]] = true;
dfs(location[0][0],location[0][1]);
if(minPathLen > 0) {
System.out.println(minPathLen);
for(int i = 0;i<=minPathLen;i++) {
System.out.print("("+minPath[i][0]+","+minPath[i][1]+") ");
}
} else {
System.out.println("Sorry");
}
}
private static int n; //行
private static int m; //列
private static int[][] maze; //迷宫
private static boolean[][] mark; //标记是否被访问
private static int[][] location;//起点和终点
private static int[][] currentPath;
private static int[][] minPath;
private static int minPathLen = Integer.MAX_VALUE;
private static int currentPathLen = 0;
private static int[][] dirMove= {{0,1},
{1,0},
{0,-1},
{-1,0}};
public static void dfs(int xx, int yy) {
//return
if(xx == location[1][0] &&
yy == location[1][1]) {
if(minPathLen > currentPathLen) {
minPathLen = currentPathLen;
for(int i = 0;i<=minPathLen;i++) {
minPath[i][0] = currentPath[i][0];
minPath[i][1] = currentPath[i][1];
}
}
currentPathLen = 0;
return;
}
for(int ii = 0;ii<4;ii++) {
int x = xx + dirMove[ii][0];
int y = yy + dirMove[ii][1];
//越界
if(x<0 || y<0 || x>=n || y>=m) {
continue;
}
//障碍物
if(maze[x][y] == 1) {
continue;
}
//
if(mark[x][y] == true)
continue;
mark[x][y] = true;
currentPathLen++;
currentPath[currentPathLen][0] = x;
currentPath[currentPathLen][1] = y;
dfs(x,y);
mark[x][y] = false;
}
}
}
广度Board-first search
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
maze = new int[n][m];
location = new int[2][2];
for(int i = 0;i<n;i++)
for(int j = 0;j<m;j++) {
maze[i][j] = in.nextInt();
}
location[0][0] = in.nextInt(); //当前点
location[0][1] = in.nextInt();
location[1][0] = in.nextInt(); //终点
location[1][1] = in.nextInt();
queue = new int[n*m][4]; //将遍历过得点存储,xy和父节点的下标和步数
mark = new boolean[n][m];
queue[0][0] = location[0][0];
queue[0][1] = location[0][1];
queue[0][2] = 0;
queue[0][3] = 0;
int x=location[0][0],y=location[0][1];
mark[x][y] = true;
boolean flag = false;
tail++;
while(head < tail) {
int xx = queue[head][0],yy = queue[head][1];
for(int i = 0;i<4;i++) {
x = xx + dirMove[i][0];
y = yy + dirMove[i][1];
if(x <0 || y<0 || x>= n || y>= m)
continue;
if(mark[x][y] == true)
continue;
if(maze[x][y] == 1)
continue;
mark[x][y] = true;
queue[tail][0] = x;
queue[tail][1] = y;
queue[tail][2] = head; //父节点
queue[tail][3] = queue[head][3]+1; //父节点步数+1
tail++;
if(x == location[1][0] && y == location[1][1]) {
flag = true;
break;
}
}
if(flag)
break;
head++;
}
System.out.println(queue[head][3]+1);
}
private static int n; //行
private static int m; //列
private static int[][] maze; //迷宫
private static int[][] location;//起点和终点
private static int queue[][]; //队列
private static int head = 0;
private static int tail = 0;
private static int len = 0;//遍历的层数
private static boolean mark[][];//标记是否被遍历
private static int[][] dirMove= {{0,1},
{1,0},
{0,-1},
{-1,0}};
}
4. 宝岛探险
宝岛由主岛和附属岛屿组成,海洋和陆地。其航拍图由二维数组矩阵组成。
问题1:统计其面积大小。广度搜索和深度搜索。
问题2:独立岛屿的个数。从某点开始给所有的点遍历,每个点及其连接点深度搜索染色,多少种颜色,多少个岛屿。
种子填充法:图像分割、物体识别。
5. 水管工游戏