재귀--여덟 여왕 문제(Java 코드 설명과 결합)

여덟 여왕 문제 진술

8개의 여왕 문제는 오래되고 잘 알려진 문제이며 역추적 알고리즘의 전형적인 사례입니다. 이 문제는 1848년 국제적인 체스 선수인 Max Bethel이 제안한 것입니다. 서로 공격할 수 없도록 8×8 그리드 체스에 8개의 퀸을 배치합니다. 즉, 두 개의 퀸은 같은 행, 같은 열 또는 같은 사선, 진자 방법이 몇 개인지 물어보십시오.

여기에 이미지 설명 삽입

여덟 여왕의 분석

(B역에 대한 여덟 여왕의 생각에 대한 한순평의 분석 참조)

  1. 첫 번째 여왕은 첫 번째 행과 첫 번째 열에 먼저 배치됩니다.
  2. 두 번째 여왕은 두 번째 행의 첫 번째 열에 놓고 괜찮은지 판단하고, 그렇지 않으면 두 번째 열과 세 번째 열에 계속 넣고 모든 열을 차례로 넣어 적절한 위치를 찾으십시오.
  3. 계속해서 세 번째 여왕, 또는 첫 번째 열, 두 번째 열... 여덟 번째 여왕도 충돌하지 않는 위치에 배치할 수 있을 때까지 올바른 해결책을 찾은 것으로 간주됩니다.
  4. 올바른 솔루션을 얻으면 스택이 이전 스택으로 롤백될 때 역추적을 시작합니다. 즉, 첫 번째 퀸과 첫 번째 열의 모든 올바른 솔루션을 얻을 수 있습니다.
  5. 그런 다음 돌아가서 두 번째 열에 첫 번째 여왕을 계속 배치한 다음 루프에서 1, 2, 3 및 4 단계를 계속 수행합니다.

설명: 이론적으로는 체스판을 표현하기 위해 2차원 배열을 만들어야 하지만, 실제로는 알고리즘을 통해 1차원 배열로도 문제를 풀 수 있다. ,2,6,1.3 } //arr에 해당하는 첨자는 어떤 행, 즉 어떤 여왕인지를 나타내며, arr[i]=val은 i+1번째 여왕을 나타내며, val+1번째 열에 위치한다. i+1번째 행.

두 여왕이 같은 행과 열에 있는지 판단하기는 쉽지만 같은 슬래시에 있는지 판단하기는 어려운 것 같습니다. 사실 여기에는 규칙이 있습니다. 두 여왕의 좌표가 (i , j) 및 ( n, m), 두 개의 퀸이 동일한 슬래시에 있는 경우 |i - n| = |j - m|.

자바 코드 구현

public class Queue8 {
    
    
    public static void main(String[] args) {
    
    
        FindQueue8Self findQueue8 = new FindQueue8Self();
        findQueue8.check(0);
    }
}

class FindQueue8Self {
    
    
    //    定义皇后的数量
    int queueAmount = 8;
    //    记录每一个皇后在棋盘上的位置,下标表示行,值表示列
    int[] queueSite = new int[queueAmount];
    //    记录8皇后在棋盘上摆法有多少种
    int count = 0;

    //递归的方法
    public void check(int n) {
    
    
//        当n = 8时,8个皇后都找好位置了,打印出8个皇后摆的位置,记录摆法次数,然后递归回溯。
        if (n == queueAmount) {
    
    
            print();
            return;
        } else {
    
    
            for (int i = 0; i < queueAmount; i++) {
    
    
//                把当前皇后摆放在第一列,第二列....,第八列
                queueSite[n] = i;
//                判断是否会有冲突,若有冲突则将当前皇后放在下一列,若无冲突,则开始在下一行开始摆放下一个皇后。
                if (judge(n)) {
    
    
                    check(n + 1);
                }
            }
        }

    }

    private boolean judge(int n) {
    
    
//        判断当前皇后和之前已经摆放好的皇后是否在同一行、同一列和同一斜线上
        for (int i = 0; i < n; i++) {
    
    
//            queueSite[i] == quequeSite[n] 判断是否在同一列
//            Math.abs(n - i) == Math.abs(queueSite[n] - queueSite[i] 判断是否在同一斜线上
            if (queueSite[i] == queueSite[n] || Math.abs(n - i) == Math.abs(queueSite[n] - queueSite[i])) {
    
    
                return false;
            }
        }
        return true;
    }

    //打印出8个皇后摆的位置,记录摆法次数
    private void print() {
    
    
        count++;
        System.out.print("第" + count + "次8皇后在棋盘上的摆放位置:");
        for (int site : queueSite) {
    
    
            System.out.print(site + " ");
        }
        System.out.println();
    }

}

시험 결과

여기에 이미지 설명 삽입

8개의 여왕을 배치하는 방법은 총 92가지입니다.

추천

출처blog.csdn.net/weixin_37977006/article/details/129385260