题目描述:
题目描述
有一个 n×n的国际象棋棋盘(n 行 n列的方格图),请在棋盘中摆放 n 个受伤的国际象棋皇后,要求:
- 任何两个皇后不在同一行。
- 任何两个皇后不在同一列。
- 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。
请问一共有多少种摆放方案。
输入描述
输入的第一行包含一个整数 n。
其中,1≤n≤10。
输出描述
输出一个整数,表示答案。
思路
1.不符合的情况下:当第一次调用时,出现这种情况,从而导致无法继续进行递归,直接返回为void。
2.符合的情况下,让count++,并对最后一行进行回溯,让它的前一列继续向前移动,进行递归。
(图片为不符合情况下)
import java.util.Scanner;
/**
* 任何两个皇后不在同一行。
任何两个皇后不在同一列。
如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。96%
*
*/
public class Time {
// n皇后变种
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int n=scanner.nextInt();
//创建一个棋盘
int[][] arr=new int[n][n];
int row = 0;
dfs(arr,row);
System.out.println(count);
}
static int count=0;
private static void dfs(int[][] arr,int row) {
//递归跳出条件1
if (row== arr.length){
count++;
return;
}
for (int col = 0; col< arr.length; col++) {
if (contins(arr,row,col)) {
arr[row][col]=1;
dfs(arr, row+1); //递归调用
arr[row][col]=0; //回溯
}
}
}//当递归一次结束后没有满足上面的递归跳出条件,说明没有完成排序需要进行回溯
//符合题意返回true,否则返回false
private static boolean contins(int[][] arr,int row, int col) {
//判断同一列是否有1
int col1=col;
for (int j = 0; j < row; j++) {
if(arr[j][col1]==1) {
return false;
}
}
int row2=row;
int col2=col;
//判断左上45度
for (int i = 0; i<3; i++) { //判断左上三格
if (row2==0||col2==0) {//当行或列的值为零的时候
if (arr[row2][col2]==1){ //并且当前值等于1,就返回false
return false;
}else {
break;
}
}
if(arr[row2--][col2--]==1) {
return false;
}
}
int row3=row;
int col3=col;
//判断右上45度
for (int i = 0; i<3; i++) {//判断右上三格
if (row3==0||col3== arr.length-1){//当前行的值等于0,或者当前列的值等于数组长度的时候
if (arr[row3][col3]==1){//并且当前值等于1的情况下,也返回false
return false;
}else {
break;
}
}
if(arr[row3--][col3++]==1) {
return false;
}
}
return true;
}
}