在棋盘上放置8个皇后,使他们互不攻击,此时每个皇后的
攻击范围为
- 同行
- 同列
- 同对角线
- 要求找出所有解
恰好每行每列放置一个皇后
如果用C[x]表示第x行皇后的列号,就成为了一个全排列问题
static int ans;
static int n;
static int[] C;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
C=new int[n];
f(0);
System.out.println(ans);
}
static void f(int cur){
if(cur==n)ans++;
else for(int i=0;i<n;i++){
int ok=1;
C[cur]=i;
for(int j=0;j<cur;j++){ //检查是否和前面的皇后冲突
//判断是否跟前面的皇后在同一列或者对角线
// 因为数组下标就是行号,所以不会在同一行
if(C[cur]==C[j]||cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j]){
ok=0;
break;
}
}
if(ok==1){
f(cur+1);
}
}
}
cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j] 这个是判断两个皇后是不是在对角线上,如果在对角线上,说明这个方法不能取
下面代码是基于上面的方法提高了效率
跟上面的代码比较,下面用二维数组来存储是否跟之前皇后冲突
就不用每次递归的时候再用for循环进行判断了
要注意的是递归的最后要进行回溯
static int ans;
static int n;
static int[] C;
static boolean[][] vis;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
C=new int[n];
vis=new boolean[3][2*n];
for(int i=0;i<3;i++){
for(int j=0;j<2*n;j++){
vis[i][j]=false;
}
}
f(0);
System.out.println(ans);
}
/**
* 可以声明一个二维数组来判断当前皇后和之前皇后位置是否冲突
*
* @param cur
*/
static void f(int cur){
if(cur==n)ans++;
else for(int i=0;i<n;i++){
if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){ //用二维数组来存放冲突位置
//cur-i+n 后面加上n的原因是因为cur-i可能是负数
C[cur]=i;
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=true;
f(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=false; //回溯
}
}
}
来源:CSDN
作者:007Peanut
链接:https://blog.csdn.net/qq_45287265/article/details/104576472