骑士周游问题又叫马踏棋盘问题
public class Main {
//定义棋盘的行数和列数
static int X = 8;
static int Y = 8;
//定义棋盘上的某个点是否被访问过
static boolean[] isVisited;
//记录是否周游结束
static boolean isFinished = false;
public static void main(String[] args) {
isVisited = new boolean[X * Y];
int[][] chessBoard = new int[X][Y];
//从第一行第一列开始走,第一次走算第一步,即step=1
travelChessboard(chessBoard,0,0,1);
//展示下chessBoard
for (int[] row: chessBoard){
for (int step: row){
System.out.print(step + " ");
}
System.out.println();
}
}
public static void travelChessboard(int[][] chessBoard,int row,int column,int step){
//假定这一点是可以走的,所以设置已访问,步数也得加上
chessBoard[row][column] = step;//假定可以走,所以先走过去看看,设置走过去的步数
isVisited[row * X + column] = true;//假定可以走,所以先走过去看看,设置成已访问
//得到下一步可以走的点的集合
ArrayList nextPoints = getNext(new Point(column, row));
while (!nextPoints.isEmpty()){
//首先取出一个来
Point nextPoint = nextPoints.remove(0);
//如果这个点没有被访问过
if (!isVisited[nextPoint.y * X + nextPoint.x]){
travelChessboard(chessBoard,nextPoint.y,nextPoint.x,step + 1);//这里我一开始写了step++ 其实应该是step+1
}
}
//如果假定失败,其实这个点是不可以走的,那么我们就进行回溯!!!
if (step < X * Y && !isFinished){
chessBoard[row][column] = 0;
isVisited[row * X + column] = false;
}else {
isFinished = true;
}
}
public static ArrayList getNext(Point curPoint){
//创建结果集
ArrayList nextPoints = new ArrayList<>();
Point nextPoint = new Point();
//可以走0
if ((nextPoint.x = curPoint.x + 2) < X && (nextPoint.y = curPoint.y - 1) >= 0){
nextPoints.add(new Point(nextPoint));
}
//表示马可以走1
if ((nextPoint.x = curPoint.x + 2) < X && (nextPoint.y = curPoint.y + 1) < Y){
nextPoints.add(new Point(nextPoint));
}
//可以走2
if ((nextPoint.x = curPoint.x + 1) < X && (nextPoint.y = curPoint.y + 2) < Y){
nextPoints.add(new Point(nextPoint));
}
//可以走3
if ((nextPoint.x = curPoint.x - 1) >= 0 && (nextPoint.y = curPoint.y + 2) < Y){
nextPoints.add(new Point(nextPoint));
}
//可以走4
if ((nextPoint.x = curPoint.x - 2) >= 0 && (nextPoint.y = curPoint.y + 1) < Y){
nextPoints.add(new Point(nextPoint));
}
//可以走5
if ((nextPoint.x = curPoint.x - 2) >= 0 && (nextPoint.y = curPoint.y - 1) >= 0){
nextPoints.add(new Point(nextPoint));
}
//可以走6
if ((nextPoint.x = curPoint.x - 1) >= 0 && (nextPoint.y = curPoint.y - 2) >= 0){
nextPoints.add(new Point(nextPoint));
}
//可以走7
if ((nextPoint.x = curPoint.x + 1) < X && (nextPoint.y = curPoint.y - 2) >= 0){
nextPoints.add(new Point(nextPoint));
}
return nextPoints;
}
}
结果略去,等结果时间太长了
2.贪心算法优化后主要是添加了这个方法
添加了这个方法后,可以减少回溯的次数,极大的提高效率
public static void getNextNext(ArrayListarrayList){ //重写集合的sort方法,将其按下一步可选点数目由小到大的顺序排列,再准确一点就是非递减排序(因为有相同点) arrayList.sort(new Comparator () { @Override public int compare(Point o1, Point o2) { //得到o1的下一步可选点的数目 int count1 = getNext(o1).size(); //得到o2的下一步可选点的数目 int count2 = getNext(o2).size(); if (count1 > count2){ return -1; }else if (count1 == count2){ return 0; }else { return 1; } } }); }
结果
1 16 43 32 3 18 45 22 42 31 2 17 44 21 4 19 15 56 53 60 33 64 23 46 30 41 58 63 54 61 20 5 57 14 55 52 59 34 47 24 40 29 38 35 62 51 6 9 13 36 27 50 11 8 25 48 28 39 12 37 26 49 10 7



