马踏棋盘
题意
给定一个棋盘大小 和一个只能走日字的马
要求马走遍所有的格子
分析
DFS搜索
1 开始搜索
2 搜索马的八个方位 判断点是否能够到达
3 更新标志位为当前步数 更新下一个点坐标 步数+1
4 搜索下一个点
5 没路走了 判断搜索是否结束 没有结束则回退坐标 并将标志位置为0 然后从坐标位置继续搜索
DFS搜索+贪心(减少搜索次数 每次都去找下下次能到达的点的个数最少的)
1 开始搜索
2 搜索马的八个方位 判断点是否能够到达
3 找下一个点能够到达的点的个数最少的点 返回最少个数 记为search1
4 搜索下一个点能够到达的点的个数 并返回给search1 记为search2
5 更新标志位为当前步数 更新下一个点坐标 步数+1
6 搜索下一个点
7 没路走了 判断搜索是否结束 没有结束则回退坐标 并将标志位置为0 然后从坐标位置继续搜索
code(java)
public class test {
static int col = 20, row = 20; // 棋盘大小
static boolean loop = false; // 递归结束条件
static int[][] vis = new int[row][col]; // 开辟棋盘空间 并且初始化为标志位 为0表示未走过
static int[] dx = new int[]{1, 2, 2, 1, -1, -2, -2, -1}; // 位移向量 即马走日
static int[] dy = new int[]{-2, -1, 1, 2, 2, 1, -1, -2};
public static void show() { // 查看当前棋盘
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
System.out.print(vis[i][j] + "\t");
}
System.out.println();
}
System.out.println("===============================================================");
}
static int minX = 0, minY = 0; // 该点记录 下一次搜索的点中 再下一次能够到达的点的个数最少的
public static int search1(int x, int y) { // 第一次搜索能够到达的点
int min = 999; // 记录下一次能够访问的点的个数最少的
for (int i = 0; i < 8; i++) {
int x1 = x + dx[i]; // 下一次到达的点
int y1 = y + dy[i];
if (x1 >= 0 && y1 >= 0 && x1 < row && y1 < col && vis[x1][y1] == 0) { // 判断是否能走
int temp = search2(x1, y1);
if (temp < min){ // 更新
min = temp;
minX = x1;
minY = y1;
}
}
}
return min;
}
public static int search2(int x, int y) { // 搜索能够到达的点的个数
int sum = 0;
for (int i = 0; i < 8; i++) {
if (loop) break;
int x1 = x + dx[i];
int y1 = y + dy[i];
if (x1 >= 0 && y1 >= 0 && x1 < row && y1 < col && vis[x1][y1] == 0) { // 判断是否能走
sum++;
}
}
return sum;
}
public static void f(int x, int y, int sum) {
if (loop == true) return; // 递归结束
if (sum == col*row) { // 所有点都访问时设置递归结束
loop = true;
return;
}
if (search1(x, y) == 999) return; //搜索下一个能走的点
vis[minX][minY] = sum+1; // 更新下一步
f(minX, minY, sum+1); // 继续搜索
if (!loop)vis[minX][minY] = 0; // 递归未结束则回退
return;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
vis[3][3] = 1; // 第一步
f(3, 3, 1);
long end = System.currentTimeMillis();
System.out.println("========消耗时间 " + (end - start) + "========");
show();
}
}