package com.wqc.horse;
import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
/**
* @author 高瞻远瞩
* @version 1.0
* @motto 算法并不可怕, 可怕的是你不敢面对它, 加油!别浮躁~冲击大厂!!!
* 马踏棋盘
*/
public class HorseChessBoard {
private static int X = 10;//表示棋盘的列 col
private static int Y = 10;//表示棋盘的行 row
private static int[][] chessBoard = new int[Y][X];
private static boolean isVisited[] = new boolean[Y * X];//是否被访问过 默认是false
private static boolean finished;//标记马是否走完全部棋盘的标志 默认为false
public static void main(String[] args) {
int row = 4;
int col = 2;
horseChessBoard(chessBoard, isVisited, row - 1, col - 1, 1);
for (int i = 0; i < chessBoard.length; i++) {
for (int j = 0; j < chessBoard[i].length; j++) {
System.out.print(chessBoard[i][j] + "\t");
}
System.out.println();
}
}
/**
* 马踏棋盘算法
*
* @param chessBoard 棋盘
* @param isVisited 标记是否被访问的标志
* @param row 马儿现在所处的行数 规定从0开始 比如row = 1 说明马儿在棋盘中的第二行
* @param col 马儿现在所处的列数
* @param step 步数 存放在棋盘中 从1开始 走完X*Y步表示完成
*/
public static void horseChessBoard(int[][] chessBoard, boolean[] isVisited, int row, int col, int step) {
//先把当前位置设置为已访问
isVisited[row * X + col] = true;
//设置棋盘的步数
chessBoard[row][col] = step;
// System.out.println("当前位置 row=" + (row + 1) + " col=" + (col + 1) + " step=" + step);
Point curPoint = new Point(col, row);
ArrayList<Point> next = next(curPoint);
next.sort(new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
return next(o1).size() - next(o2).size();
}
});//优化代码 对next集合所有可以走的选择中的每一个选择的的next集合大小进行排序 每次把小的放在最前面 递归可以选择最少的next集合
//这样可以减少回溯的次数 贪心思想
while (!next.isEmpty()) {
Point point = next.remove(0);//取出集合的第一种可能 取走就把它从集合中删除了
//如果当前位置没有被访问 就进行递归
if (!isVisited[X * point.y + point.x]) {
horseChessBoard(chessBoard, isVisited, point.y, point.x, step + 1);
}
}
//当结束while循环的时候 回溯的时候进行以下判断
if (!finished && step < X * Y) {//如果步数小于36步且没有完成 说明没有结束 将当前的步数置为0 并标记为没有访问
// chessBoard[row][col] = 0;//把当前位置设为0
isVisited[X * row + col] = false; //当前位置走不通了 把当前位置设为false 进行回溯 相当于悔棋
} else {
finished = true;//只要这一步完成 说明棋盘的所有位置都被访问过
}
}
/**
* 获取到马走下一步还有哪些选择 放在ArrayList集合中返回
*
* @param newPoint 传入马儿的坐标点
* @return 返回所有情况的集合
*/
public static ArrayList<Point> next(Point newPoint) {
ArrayList<Point> ls = new ArrayList<>();
Point point = new Point();
//一共有8种情况
if ((point.x = newPoint.x + 2) < X && (point.y = newPoint.y - 1) >= 0) {
ls.add(new Point(point.x, point.y));
}//0
if ((point.x = newPoint.x + 2) < X && (point.y = newPoint.y + 1) < Y) {
ls.add(new Point(point.x, point.y));
}//1
if ((point.x = newPoint.x + 1) < X && (point.y = newPoint.y + 2) < Y) {
ls.add(new Point(point.x, point.y));
}//2
if ((point.x = newPoint.x - 1) >= 0 && (point.y = newPoint.y + 2) < Y) {
ls.add(new Point(point.x, point.y));
}//3
if ((point.x = newPoint.x - 2) >= 0 && (point.y = newPoint.y + 1) < Y) {
ls.add(new Point(point.x, point.y));
}//4
if ((point.x = newPoint.x - 2) >= 0 && (point.y = newPoint.y - 1) >= 0) {
ls.add(new Point(point.x, point.y));
}//5
if ((point.x = newPoint.x - 1) >= 0 && (point.y = newPoint.y - 2) >= 0) {
ls.add(new Point(point.x, point.y));
}//6
if ((point.x = newPoint.x + 1) < X && (point.y = newPoint.y - 2) >= 0) {
ls.add(new Point(point.x, point.y));
}//7
return ls;
}
}
java实现马踏棋盘算法-------参考视频 韩顺平《java数据结构和算法》
最新推荐文章于 2024-05-08 15:24:52 发布