八个皇后在8x8的棋盘上,要求他们放置的位置(两两)不能在同一行、同一列和同一斜线上,问有几种摆法
首先先明确怎么不能在同一行,同一列和同一对角线上
如果我们的定义一个二维数组int[][] nums= ne int[8][8]
,(i,j)
代表第n
个皇后所在位置,那么两个皇后不在同一行和同一列,就是i
值不等、j
值也不等。
明确这个问题之后,怎么保证不在同一个斜线上呢?在n*n
的矩形里,所谓的斜线和边的夹角为45°,那么可以得到,|x1 - x2| = |y1 - y2|
的,所以就是|i1 - i2| = |j1 - j2|
。
为了方便后续操作,我们将二维数组nums
简化为一维数组arr
,i
代表n
个皇后所在横坐标 arr[i]
代表第n
个皇后所在纵坐标,所以就是(i,arr[i])
,所以判断斜线就是|i1 - i2| =| arr[i1] - arr[i2] |
。
那么我们的写法就是:
/**
* @author 我见青山多妩媚
* @date Create on 2023/3/15 10:22
*/
public class EightQueens {public static void main(String[] args) {QueensPut queensPut = new QueensPut();//棋盘 8 * 8 8个皇后,arr下标代表皇后所在第i行,arr[i]代表第arr[i]列 第i个皇后所在位置为(i,arr[i])int[] arr = new int[8];//防止第1个皇后开始queensPut.putQueen(arr,0);}
}class QueensPut{int count = 0;public void putQueen(int[] arr,int n){//找到一种满足的情况if(n == 8){count++;System.out.println("第"+count+"种:");printQueue(arr);return;}for(int i = 0;i<8;i++){//第n个皇后的第i种摆法arr[n] = i;if(verity(arr,n)){//如果没冲突,递归继续n+1个皇后的放置方法,有冲突就从i++里面找putQueen(arr,n+1);}}}//检查第m个皇后和前m-1个皇后摆放位置是否有冲突boolean verity(int[] arr,int m){for(int i = 0;i//m > i 所以只需要判断是否所在同一列 arr[i] == arr[m]//如果在同一对角线,那么 |i - j| == |arr[i] - arr[j]|if(arr[i] == arr[m] || Math.abs(m - i ) == Math.abs(arr[i] - arr[m])){return false;}}return true;}//数组arr转为二维数组,打印皇后所在位置public void printQueue(int[] arr){for (int k : arr) {for (int j = 0; j < arr.length; j++) {//一维数组转化为二维数组过程中,当arr[i] == j,// 即因为j也是从0开始,相当于找到arr[i] = i的时候,说明这个数时有值的 不是0,是皇后放的位置char num = k == j ? 'Q' : '-';System.out.print(num+" ");}System.out.println();}}public int getCount(){return this.count;}
}
运行结果:
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
力扣-51 N皇后
有了八皇后为基础,那么n皇后其实也好写了
/*** @author 我见青山多妩媚* @date Create on 2023/3/15 11:10*/
public class NQueens {List> lists = new ArrayList<>();public List> solveNQueens(int n) {int[] arr = new int[n];putQueens(arr,0,n);return lists;}void putQueens(int[] arr,int m,int n){if(n == m){toStringArray(arr);return;}for(int i = 0;iarr[m] = i;if(verity(arr,m)){putQueens(arr,m+1,n);}}}boolean verity(int[] arr,int m){for(int i = 0;iif(arr[i] == arr[m] || Math.abs(i - m) == Math.abs(arr[i] - arr[m])){return false;}}return true;}void toStringArray(int[] arr){List list = new ArrayList<>();for(int k : arr){StringBuilder builder = new StringBuilder();for(int j = 0; jbuilder.append(k == j ? "Q" : ".");}list.add(builder.toString());}lists.add(new ArrayList<>(list));}
}