思路:八皇后这么经典的问题相信大家都已经知道题目的意思了,那要怎么做呢?
看个例子:绿色这个点能存在的前提是,它的左下方的那条斜线上、右上方那条斜线上以及它所在的这一列和这一行上
,都没有其他“皇后”,这样一看我们搜索时所需的四个条件就出来了。
根据题目的意思我们最后要输出一个数组,拿题目所给的那个例子2,4,6,1,3,5
意思是第一行的“皇后”应该放在第2列上,第二行的皇后放在第4列上,以此类推,因此我们就可以用一维数组来表示所有的状态即arr[i]=j 第i行的皇后应该放在第j列
,用这种方式表示我们就可以不用判断同一行上是否还有其他“皇后”,因为搜索的时候是从下面一层往上来的,这样就肯定不会在同一行。
现在还有三个条件分别是1.左下方斜线 2.右上方斜线 3.同一列上
,我们从图中看看其中的关系
字丑希望不要介意
我们可以分别用数组来判断判断该点的左斜右斜是否已经存在“皇后”
left[x+y]=true 表示x,y这点的左斜已经有皇后了,left[x+y]=boolean,则表示没有
。
举例子的那个点比较特殊,x-y不会小于零,但是在实际操作中会有小于零的点因此我们要把每个x-y的值都加上n来确保坐标不为负数right[x-y+n]
,至于为什么不用绝对值大家可以试一下。
判断都一列上是否已经存在“皇后”,跟上面一样再开个数组。
代码如下:
import java.util.Scanner;
public class Main {
static boolean left[]=new boolean[40]; //:左上到右下 在同一条斜线上的横坐标减纵坐标绝对值相等
static boolean right[]=new boolean [40]; //:右上到左下 在同一条斜线上的横坐标加纵坐标值相等
static boolean lie[]=new boolean[40];
static int count=0; //计算个数,超过三个就不输出了
static int a[]=new int[40];
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
DFS(1,n);
System.out.println(count);
}
public static void DFS(int x,int n) {
if(x>n) {
if(count<=2){
for(int i=1;i<=n;i++)
System.out.print(a[i]+" ");
System.out.println();
}
count++;
return ;
}
for(int i=1;i<=n;i++) {
if(!lie[i]&&!left[x-i+n]&&!right[x+i]) {
lie[i]=true;
left[x-i+n]=true;
right[x+i]=true;
a[x]=i;
DFS(x+1,n);
//回溯
lie[i]=false;
left[x-i+n]=false;
right[x+i]=false;
}
}
}
}