什么是八皇后问题?

八皇后问题:
在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。

思路分析:

  1. 每次放一行,从第1行开始。
  2. 每进入新的一行就从第1列开始
  3. 判断是否符合规则。
  4. 如果符合规则就进去下一行。
  5. 不符合规则就放在下一列。
  6. 如果将当前行的所有列放完都没有找到匹配规则的地方,就返回上一行的位置。
  7. 返回上一行的位置之后,将棋子继续往后面移动。从思路的第三点进行。
  8. 如果棋子将8行全部放完,返回第7行,将当前的棋子往下一列移动。判断,从思路三开始。

这样就会遍历所有的棋子

比如说当第一行棋子放在第一列时。

0 4 7 5 2 6 1 3 
0 5 7 2 6 3 1 4 
0 6 3 5 7 1 4 2 
0 6 4 7 1 3 5 2 

  1. 进入第二行,第一列不符合,匹配下一列,知道第5列符合规则,就进去第三行。
  2. 第三行,从第一列开始知道第8列符合,进去第四列
  3. 第四行,知道第6列符合,进入下一列。
  4. ······
  5. 第八行,第4列符合规则,此时8行全部放完了,返回第七列。
  6. 第七列刚才放在了第二列,此时往后移一列,放在第3列,看是否符合,一直到第8列都不符合,返回第六列。
  7. 第六列也没有符合的,继续返回上一行
  8. ······
  9. 当返回第二行的时候,上次在第5列,往后移,也就是第6列,判断符合规则,进去第三列,继续判断。
    10.直到第一行后面的遍历完,返回第一行,将第一行的位置移到第二列,继续判断。

我们这里用一个一维数组arr【8】 来存储
数组的索引代表行,元素代表列。

代码:

package recursion.queen8;



public class Queen {
    public static void main(String[] args) {
        Queen game = new Queen();
        game.check(0);
        System.out.println(count);
    }

    private static int count;

    //代表最大的行数和列数
    private final int MAX = 8;
    //用index代表行数,数组中的值代表列数
    private int[] arr = new int[MAX];
    public Queen() {
    }

    //用来放置棋子
    //n代表放置的式第几行

    public void check(int n){
        //如果n=8,说明前8行已经放好了,就输出并退出
        if (n==8){
            show();
            return;
        }
        //从第一列一直放到最后一列,进行一个遍历
        for (int i =0 ;i < MAX;i++){
            //arr[n]=i;代表的的就是n*i这和位置有棋子 在第n行把棋子放在第i列
            arr[n]=i;
            //判断放在第n行的棋子是否符合规范
            if (rule(n)){
                //如果符合规范就放下一行。
                check(n+1);
            }
        }
    }


    //用来检查所放置的棋子是否符合规则

    //n代表的式现在为现在判断的式第n行的棋子
    public boolean rule(int n){

        //i 代表的n之前的行数
        for (int i =0 ; i < n;i++){
            //arr[i]==arr[n]看前几行是否和现在放的棋子在同一列,Math.abs(n-i)==Math.abs(arr[i]-arr[n]))判断是否在斜线上,列数相差的绝对值和行数相差的绝对值作比较
            if (arr[i]==arr[n]||Math.abs(n-i)==Math.abs(arr[i]-arr[n])){
                return false;
            }
        }

        return true;

    }
    //用来输出结果
    public void show() {

        for (int i = 0; i < MAX; i++) {
            System.out.print(arr[i] + " ");
        }
        count++;
        System.out.println();
    }

}

结果:

0 4 7 5 2 6 1 3 
0 5 7 2 6 3 1 4 
0 6 3 5 7 1 4 2 
0 6 4 7 1 3 5 2 
1 3 5 7 2 0 6 4 
1 4 6 0 2 7 5 3 
1 4 6 3 0 7 5 2 
1 5 0 6 3 7 2 4 
1 5 7 2 0 3 6 4 
1 6 2 5 7 4 0 3 
1 6 4 7 0 3 5 2 
1 7 5 0 2 4 6 3 
2 0 6 4 7 1 3 5 
2 4 1 7 0 6 3 5 
2 4 1 7 5 3 6 0 
2 4 6 0 3 1 7 5 
2 4 7 3 0 6 1 5 
2 5 1 4 7 0 6 3 
2 5 1 6 0 3 7 4 
2 5 1 6 4 0 7 3 
2 5 3 0 7 4 6 1 
2 5 3 1 7 4 6 0 
2 5 7 0 3 6 4 1 
2 5 7 0 4 6 1 3 
2 5 7 1 3 0 6 4 
2 6 1 7 4 0 3 5 
2 6 1 7 5 3 0 4 
2 7 3 6 0 5 1 4 
3 0 4 7 1 6 2 5 
3 0 4 7 5 2 6 1 
3 1 4 7 5 0 2 6 
3 1 6 2 5 7 0 4 
3 1 6 2 5 7 4 0 
3 1 6 4 0 7 5 2 
3 1 7 4 6 0 2 5 
3 1 7 5 0 2 4 6 
3 5 0 4 1 7 2 6 
3 5 7 1 6 0 2 4 
3 5 7 2 0 6 4 1 
3 6 0 7 4 1 5 2 
3 6 2 7 1 4 0 5 
3 6 4 1 5 0 2 7 
3 6 4 2 0 5 7 1 
3 7 0 2 5 1 6 4 
3 7 0 4 6 1 5 2 
3 7 4 2 0 6 1 5 
4 0 3 5 7 1 6 2 
4 0 7 3 1 6 2 5 
4 0 7 5 2 6 1 3 
4 1 3 5 7 2 0 6 
4 1 3 6 2 7 5 0 
4 1 5 0 6 3 7 2 
4 1 7 0 3 6 2 5 
4 2 0 5 7 1 3 6 
4 2 0 6 1 7 5 3 
4 2 7 3 6 0 5 1 
4 6 0 2 7 5 3 1 
4 6 0 3 1 7 5 2 
4 6 1 3 7 0 2 5 
4 6 1 5 2 0 3 7 
4 6 1 5 2 0 7 3 
4 6 3 0 2 7 5 1 
4 7 3 0 2 5 1 6 
4 7 3 0 6 1 5 2 
5 0 4 1 7 2 6 3 
5 1 6 0 2 4 7 3 
5 1 6 0 3 7 4 2 
5 2 0 6 4 7 1 3 
5 2 0 7 3 1 6 4 
5 2 0 7 4 1 3 6 
5 2 4 6 0 3 1 7 
5 2 4 7 0 3 1 6 
5 2 6 1 3 7 0 4 
5 2 6 1 7 4 0 3 
5 2 6 3 0 7 1 4 
5 3 0 4 7 1 6 2 
5 3 1 7 4 6 0 2 
5 3 6 0 2 4 1 7 
5 3 6 0 7 1 4 2 
5 7 1 3 0 6 4 2 
6 0 2 7 5 3 1 4 
6 1 3 0 7 4 2 5 
6 1 5 2 0 3 7 4 
6 2 0 5 7 4 1 3 
6 2 7 1 4 0 5 3 
6 3 1 4 7 0 2 5 
6 3 1 7 5 0 2 4 
6 4 2 0 5 7 1 3 
7 1 3 0 6 4 2 5 
7 1 4 2 0 6 3 5 
7 2 0 5 1 4 6 3 
7 3 0 2 5 1 6 4 

共有92个结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vivien_o.O

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值