searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

算法基础-八皇后问题-暴力遍历法

2023-08-04 09:58:32
7
0

1.八皇后规则简述

8*8的国际象棋棋盘上摆放8个皇后,要求

1.任意两个皇后不能处于同一行或同一列

2.任意两个皇后不能处于同一斜线上

2.解题思路

设满足提议你的解的两个皇后的位置为A(x1,y1),B(x2,y2),则根据规则 A和B有关系:

  1. x1不等于x2 (不同行)

  2. y1不等于y2 (不同列)

  3. |x1-x2|不等于|y1-y2|(不处于同一斜线的约束)

由于结果记录的是8*8棋盘的坐标值,所以结果是二位(x,y)的形式,而由于皇后不能处于同一行,这说明符合条件的8个坐标点一定是 1~8(因为8个皇后都要放置在棋盘上,结果必定是每一行有一个皇后),所以存储结果的二维数组可以简化为一维数组,数组的下标对应的就是各个行(x),数组的值就是该皇后放置的列(y);

如 int[0]=1,表示该皇后放在第一行第二列上;

3.解题主要方法

1.获得结果时打印

public static void resultPrint() {
    count++;
    for (int i : result) {
        System.out.print(i);
    }
    System.out.println();
}

2.判断当前结果是否符合

public static boolean charge(int n) {
    for (int i = 0; i < n; i++) {
        if (result[i] == result[n] //不在同一行,因为用一维数据记录结果,本来就不在同一行
                || Math.abs(result[i] - result[n]) == Math.abs(n - i)//不在同一斜线上
        ) {
            return false;
        }
    }
    return true;
}

3.放置皇后

 
public static void check(int n) {
    if (n == max) {
        //当前如果已经放置到第9行(max==8,从0开始遍历,当前是第9行),
        //说明前8行已经完成放置,则已经得到一种题解
        resultPrint();
        return;
    }
    for (int i = 0; i < max; i++) {
        //在第n行放置在第i列,然后判断放置之后的结果是否满足约束(i范围0~7)
        result[n] = i;
        if (charge(n)) {
            //当前位置满足条件,则递归放置下一行的皇后
            check(n + 1);
        }
        //如果当前i(列)不满足,则继续遍历下一列尝试,直至所有列都不可以,则退出
    }
}

4.主方法调用

 public static void main(String[] args) {
    check(0);
    System.out.println("总共解法:" + count);
}

5.源码

public class Queue8 {
    public static int max = 8;
    public static int count = 0;
    public static int[] result = new int[max];

    public static void main(String[] args) {
        check(0);
        System.out.println("总共解法:" + count);
    }

    public static void check(int n) {
        if (n == max) {
            //当前如果已经放置到第9行(max==8,从0开始遍历,当前是第9行),
            //说明前8行已经完成放置,则已经得到一种题解
            resultPrint();
            return;
        }
        for (int i = 0; i < max; i++) {
            //在第n行放置在第i列,然后判断放置之后的结果是否满足约束(i范围0~7)
            result[n] = i;
            if (charge(n)) {
                //当前位置满足条件,则递归放置下一行的皇后
                check(n + 1);
            }
            //如果当前i(列)不满足,则继续遍历下一列尝试,直至所有列都不可以,则退出
        }
    }


    public static boolean charge(int n) {
        for (int i = 0; i < n; i++) {
        //不在同一列,因为用一维数据记录结果,本来就不在同一行
            if (result[i] == result[n] 
                    //不在同一斜线上
                    || Math.abs(result[i] - result[n]) == Math.abs(n - i)
            ) {
                return false;
            }
        }
        return true;
    }

    public static void resultPrint() {
        count++;
        for (int i : result) {
            System.out.print(i);
        }
        System.out.println();
    }

}
0条评论
0 / 1000
粟振超
2文章数
0粉丝数
粟振超
2 文章 | 0 粉丝