八皇后算法描述如下:在8×8格的国际象棋上摆放八个皇后,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
原理: 八皇后类似题需要列举出所有的可能性,用回溯的方法更好。每次n个为装满后return,就在上次n-1的位置,继续for下次的不同位置,判断能不能装满,还是都不行就继续回溯到n-2开始不同位置的判断,以此类推,直到列举输出全部的可能性。
八皇后需要解决的重点代码:其实重点就二点,一个是for的回溯遍历与下一次的装填,另一个是每次装填时的判断能否装填。
上代码!
第一个问题:我们用一个一维数组装就可以了,
因为同一行只能有一个,arryy【n】表示列,n表示行就可以了,每次for来装每行仅有的那个。
static public void check(int n){
if(n==8){//这个if别看很多,其实就是一个结束条件,以及将装好的输出出来十分简单的逻辑
count++;//每次装成功一次就++
System.out.println(" 这是第"+count+"个");
System.out.println(" ");
int arry[][]=new int[8][8];
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
arry[i][j]=0;//每次将初试化为1
}
}
for (int a=0;a<8;a++){
arry[a][arryy[a]-1]=1;//将装好的位置的赋值上去
}
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
System.out.print(arry[i][j]);//输出
System.out.print(" ");
}
System.out.println(" ");
}
return;//当每次装完后,在n-1的基础上再次进行for的下次循环,以此类推
}
else {
for (int i=1;i<9;i++){//赋值给数组arryy
arryy[n]=i;//将1到9的数赋值到arryy中,arryy【n】实际表示的是第n行的列数,n表示为行数
if(jude(n)){//判断jude(n)能否加入
check(n+1);
}
}
}
}
第二个问题:八皇后就是同一行,同一列,同一斜边不能有。
arryy[i]==arryy[n]:不能同一列
Math.abs(i-n)==Math.abs(arryy[i]-arryy[n]:不能同一斜边
同一斜边的关系是列数与行数的绝对值相差相同
static public boolean jude(int n){
for (int i=0;i<n;i++){//小于n不能为8,不然遍历到后肯定会有0等于0
if(arryy[i]==arryy[n] || Math.abs(i-n)==Math.abs(arryy[i]-arryy[n]) ){
return false;
}
}return true;
}
全部代码:
public class 八皇后 {
static int arryy[]=new int[8];
static int count;
public static void main(String[] args) {
check(0);
}
static public void check(int n){
if(n==8){
count++;
System.out.println(" 这是第"+count+"个");
System.out.println(" ");
int arry[][]=new int[8][8];
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
arry[i][j]=0;//每次将初试化为1
}
}
for (int a=0;a<8;a++){
arry[a][arryy[a]-1]=1;//将装好的位置的赋值上去
}
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
System.out.print(arry[i][j]);//输出
System.out.print(" ");
}
System.out.println(" ");
}
return;//当每次装完后,在n-1的基础上再次进行for的下次循环,以此类推
}
else {
for (int i=1;i<9;i++){//赋值给数组arryy
arryy[n]=i;//将1到9的数赋值到arryy中,arryy【n】实际表示的是第n行的列数,n表示为行数
if(jude(n)){//判断jude(n)能否加入
check(n+1);
}
}
}
}
static public boolean jude(int n){
for (int i=0;i<n;i++){//小于n不能为8,不然遍历到后肯定会有0等于0
if(arryy[i]==arryy[n] || Math.abs(i-n)==Math.abs(arryy[i]-arryy[n]) ){
return false;
}
}return true;
}
}