고전 알고리즘 (21)은 여덟 개 졸업자 퀸즈 문제 [알고리즘] 것

사설 : 나는 "바다 항해는"별명이 내 여자 친구의 이름의 이름에서 유래뿐만 아니라입니다. 나는 사랑의 기술, 오픈 소스 사랑, 사랑의 프로그래밍. 技术是开源的、知识是共享的.

이 블로그는 조금 요약하고있는 경우, 자신의 학습을 기록 자바는 , 알고리즘 관심, 당신은 내 동적에 초점을 맞출 수 있습니다, 우리는 함께 배운다.

用知识改变命运,让我们的家人过上更好的生活.

관련 기사

보기 알고리즘에 여기를 클릭 [시리즈] 블로그 기사


문제 1. 설명

八皇后问题고대의 잘 알려진 문제가 역 추적 알고리즘의 대표적인 경우이다. 국제 체스 선수 1848 년 최대 베델에 의해 제기 된 문제는 : 在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上얼마나 많은 진자 방법을 물었다. 가우스 프로그램 76 종류가있다 생각합니다. 1854 베를린에서 다른 체스 잡지에 다른 솔루션 40 종류의 출판, 다음 사람은 그래프 이론을 사용하여 결과를 92 종류의 해결. 컴퓨터의 발명하면이 문제를 해결할 수 컴퓨터 다양한 프로그래밍 언어들이 존재한다.

나는 우리가 연주 한 생각 死亡八皇后游戏여기에 내가 온라인 게임 기록 화면을 재생할 것입니다.

그림 삽입 설명 여기

2, 문제 분석

목적 : 장소 팔 체스 8 × 8 격자 퀸즈

규칙 : 두 퀸즈 같은 라인, 동일한 열 또는 동일한 대각선 수 없다

상기 퀸 각 행 업 퀸 넣어 그래서 어떤 피어 수 없으므로
행수 수 퀸 동일하기 때문에, 각각의 행은 적어도 퀸있다.

결론 :每一行一定是放一个皇后

3 로직을 달성

그림 삽입 설명 여기

① 먼저, 첫번째 라인 퀸 체스 컬럼 1의 1 내지 8 × 8 그리드

② 그 다음 두 번째 행의 첫 번째 열을 넣어, 다음 규칙이 충족되는지 여부를 결정하기 위해 노력하고, 두 번째 여왕을 넣어. 그렇지 않을 경우, 두 번째 열에 시도를 계속, 세 번째 열 위치는 ... 모두의 모든 열을 넣어 시도 완성 된, 적당한 위치를 찾을 수 있습니다.

세 번째 여왕을 넣어 계속 및 배치 프로세스 단계 ② 공감 ③.

... ...

④ 그래서, 네 번째, 다섯 번째, 여섯 번째, 일곱 번째, 여덟 번째 퀸 넣어

⑤ 때 때 올바른 해결책을 얻을 수 있습니다 :

여덟 번째 시도가 다른 방법 장소가없는 있는지 확인하기 위해, 여왕의 위치를 이동;
의 볼 일곱 번째 여왕의 위치를 이동하려고 다른 방법 장소가없는 경우,
여섯 번째 퀸즈의 위치를 이동하려고,보기 두는 다른 방법이 없다
... ...
등등, 다섯째 넣어 다른 방법이없는 경우 표시 여왕 이동 네번째, 세번째, 두번째 위치.
이것은 첫 번째 행에서, 첫 번째 열에 모든 가능성 최초의 여왕이었다

⑥ 다시 싸이클 뒤에 넣어 제 퀸의 첫 번째 열을 계속 계속, ②, ③, ④, ⑤ 상기 ① 단계를 수행

그 과정에서 사용하려면 回溯算法, 생각의 从一条路往前走,能进则进,不能进则退回来,换一条路再试。요구 사항을 충족하는 위치가 존재하지 않는 경우 여덟 퀸즈 전형적인 문제가 여왕을 넣어하기 위해 첫 번째 단계는 알고리즘을 역 추적 한 다음 요구 사항에 맞춰 두 번째 단계는 첫 두 여왕을 넣어, 우리는 먼저 변경해야합니다 당신이 그것을에 자격을 갖춘 위치를 찾을 때까지 여왕의 위치, 두 여왕의 위치를 재 출시.

위로의 미로 검색 문제가 매우 일반적인 사용이 도로가 막 다른 골목이다, 그 이전의 교차로로 돌아가 길을 계속합니다.

使用一个一维数组表示皇后的位置,其中数组的下标表示皇后所在的行,也就是第几个皇后,数组元素的值表示皇后所在的列。

4, 코드 구현

package com.study.algorithm;

/**
 * @Description:
 * @Author: 扬帆向海
 * @Date: Created in 01:26 2020/4/4
 */
public class EightQueens {

    static final int COUNT = 8;

    /**
     * 用一维数组存放皇后的摆放位置
     */
    static int[] array = new int[COUNT];
    /**
     * 用来记录有多少种摆放方案
     */
    static int sum = 0;

    public static void main(String[] args) {
        putQueen(0);
        System.out.println("八皇后总共有" + sum + "种摆放方案");
    }

    /**
     * 在棋盘上摆放皇后
     *
     * @param n 第几个皇后
     */
    public static void putQueen(int n) {
        // 如果n=COUNT,表示皇后放置完毕
        if (n == COUNT) {
            System.out.print((sum + 1) + "、八皇后的摆放位置是:");
            for (int i = 0; i < COUNT; i++) {
                int pos = array[i] + 1;
                System.out.print(pos + " ");
            }
            System.out.println();
            System.out.print("摆放位置如下图所示:");
            printPlace();
            return;
        } else {
            // 依次往棋盘中放入皇后
            for (int i = 0; i < COUNT; i++) {
                // 先把当前这个皇后n,放到该行的第一列
                array[n] = i;
                // 调用方法,判断把第n个皇后在第i列时,是否有冲突
                if (checkPlace(n)) {
                    // 不冲突,接着放置第(n+1)个皇后,即开始递归
                    putQueen(n + 1);
                }
            }
        }
    }

    /**
     * 绘制COUNT×COUNT棋盘,打印皇后的位置
     */
    public static void printPlace() {
        System.out.println();
        sum++;
        for (int i = 0; i < COUNT; i++) {
            System.out.print(" ");
            for (int j = 0; j < COUNT; j++) {
                System.out.print("---");
            }
            System.out.println();
            for (int k = 0; k < COUNT; k++) {
                if (k == array[i]) {
                    System.out.print("|" + "♛");
                } else {
                    System.out.print("| " + " ");
                }
            }
            System.out.println("|");
        }
        System.out.print(" ");
        for (int i = 0; i < COUNT; i++) {
            System.out.print("---");
        }
        System.out.println();
    }

    /**
     * 检查皇后的摆放位置是否有冲突
     *
     * @param n 表示第几个皇后
     * @return
     */
    public static boolean checkPlace(int n) {
        for (int i = 0; i < n; i++) {
            // 一维数组的值表示该行的列值,如果值相同,则表示在同一列
            // n-i表示两个皇后相差几行,array[n]-array[i]表示相差几列,如果相减的绝对值相等,则表示在对角线上
            if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
                return false;
            }
        }
        return true;
    }
}

코드의 실행 결과 :

总共有 92 种摆放方案,由于篇幅有些,在此只截取了两种方案。

그림 삽입 설명 여기

그림 삽입 설명 여기


제한으로, 블로그는 필연적으로 몇 가지 실수있을 것입니다, 부주의 날개 거물급의 누설 당신이 간청에있다!

게시 된 101 개 원래 기사 · 원 찬양 4287 ·은 790,000 + 조회수

추천

출처blog.csdn.net/weixin_43570367/article/details/104495769