/**
* @author zc
*/
public class ChessTwo {
/**国际象棋棋盘建模*/
static int[][] CHESS = new int[8][8];
/**皇后数量*/
final static Integer QUEEN_COUNT = 8;
/**皇后所在位置*/
final static int QUEEN_LOCATION = 1;
/**可使用位置*/
final static int USE_LOCATION = 0;
/**统计解法*/
static int count;
public static void main(String[] args) {
putQueen(0);
System.out.println("解法:"+count+"种");
}
/**
* 放置皇后
* @row 第几行
*/
private static void putQueen(int row){
//当8个皇后放置完成后,退出循环并打印
if(row == QUEEN_COUNT){
//统计解法
count++;
System.out.println("第"+count+"种:");
//打印解法的排列模型
showArray();
//终止代码向下继续循环
return;
}
//尝试在当前行的每一列尝试放置皇后
for (int col = 0; col < CHESS.length; col++) {
//检测row行col列放置是否安全
if(isSafe(row,col)){
//放置皇后
CHESS[row][col] = QUEEN_LOCATION;
//递归当前方法,继续为下一行放置皇后
putQueen(row + 1);
//将放置的皇后数据清空,方便回溯
CHESS[row][col] = USE_LOCATION;
}
}
}
/**
*
* @param x1 行
* @param y1 列
* @return 当前放置的皇后是否合法:与之前所有的皇后是否存在冲突
*/
private static boolean isSafe(int x1,int y1){
/**遍历CHESS,判断当前行放置的皇后位置是否与之前所放置的皇后冲突
* 不在同一列、不在同一斜边
* 思路:
* 1、找到当前行皇后的坐标
* 2、找到之前每一行皇后的坐标
* 3、将当前行皇后的坐标与之前行皇后的坐标一一对比,判断是否产生冲突
* */
//遍历之前所有行
for (int i = 0; i < x1; i++) {
//遍历列,找到之前每一列皇后所在位置
for (int j = 0; j < CHESS.length; j++) {
//定位已放置皇后位置
if(CHESS[i][j] == QUEEN_LOCATION){
/**
*排除列、排除斜边
*斜率计算公式:k = (row1-row2)/(col1-col2),由于皇后的攻击范围为米字型,左右斜率的绝对值就始终都为1
*最终公式演化为:(row1-row2) = (col1-col2)
*/
if(y1 == j || Math.abs(x1-i)==Math.abs(y1-j)) {
return false;
}
}
}
}
return true;
}
/**
* 打印结果
*/
private static void showArray(){
for (int i = 0; i < CHESS.length; i++) {
for (int j = 0; j < CHESS.length; j++) {
System.out.print(CHESS[i][j]+" ");
}
System.out.println();
}
System.out.println();
}
回溯算法这么玩:如何实现八皇后
最新推荐文章于 2024-08-08 15:12:59 发布