八皇后問題解法

八皇后問題解法

什么事八皇后問題

國際象棋中的皇后,可以橫向、縱向、斜向移動。如何在一個8X8的棋盤上放置8個皇后,使得任意兩個皇后都不在同一條橫線、豎線、斜線方向上?

解題思路

從第一排第一個位置放置第一個皇后,然后開始第二排,第二排第一個被封鎖,第二個也被封鎖,第三個可用,開始第三排,一排排循環向下,一旦遇到整排不可用,則表示前一排擺放錯誤,將上一排位置向后移動一個.這種向下遞歸搜索是否有解,失敗則回退到循環換別的方式的解題方式就是遞歸回溯法,常見的一種算法思路,現在看一下遞歸回溯法如何解八皇后問題.

PHP遞歸回溯法解八皇后問題

Talk is cheap,show you my code!

<?php

class Queen8
{
    /**
     * 棋盤大小
     */
    const MAX_NUM = 8;
    /**
     * @var array 二維數組模擬棋盤
     */
    public $chess_board;

    /**
     * 構造棋盤
     * Queen8 constructor.
     */
    public function __construct()
    {
        for ($i = 0; $i < self::MAX_NUM; $i++) {
            for ($j = 0; $j < self::MAX_NUM; $j++) {
                $this->chess_board[$i][$j] = 0;
            }
        }
    }

    /**
     * 檢查對應點能否放皇后
     * @param int $x
     * @param int $y
     * @return bool
     */
    public function check(int $x, int $y)
    {
        for ($i = 0; $i < $y; $i++) {
            // 軸檢查豎
            if (1 == $this->chess_board[$x][$i]) {
                return false;
            }
            // 檢查左斜方向,只需檢查上側
            if ($x-1-$i >= 0 && 1 == $this->chess_board[$x-1-$i][$y-1-$i]) {
                return false;
            }
            // 檢查右斜方向,只需檢查上側
            if ($x+1+$i < self::MAX_NUM && 1 == $this->chess_board[$x+1+$i][$y-1-$i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 從上下到放皇后
     * @param int $y
     * @return bool
     */
    public function settleQueen(int $y)
    {
        // 行數超過八行則表示已經全部擺放完畢
        if ($y == self::MAX_NUM) {
            return true;
        }

        for ($i = 0; $i < self::MAX_NUM; $i++) {
            for ($x = 0; $x < self::MAX_NUM; $x++) {
                $this->chess_board[$x][$y] = 0;
            }
            if ($this->check($i, $y)) {
                $this->chess_board[$i][$y] = 1;
                if ($this->settleQueen($y + 1)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 打印結果
     */
    public function printChessBoard()
    {
        foreach ($this->chess_board as $item) {
            foreach ($item as $point) {
                echo $point;
            }
            echo PHP_EOL;
        }
    }

}
$queen8 = new Queen8();
$queen8->settleQueen(0);
$queen8->printChessBoard();

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問題介紹 摘自百度百科八皇后問題,是一個古老而著名的問題,是回溯算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟...
    逍遙wqy閱讀 1,131評論 0 0
  • 回溯算法 回溯法:也稱為試探法,它并不考慮問題規模的大小,而是從問題的最明顯的最小規模開始逐步求解出可能的答案,并...
    fredal閱讀 13,728評論 0 89
  • 八皇后問題:在8*8的棋盤上放置8個皇后,保證任意兩個皇后之間不能相互攻擊。(即沒有兩個皇后是在同一行、同一類、或...
    五秋木閱讀 769評論 0 0
  • 問題描述 n皇后問題是將n個皇后放置在n*n的棋盤上,皇后彼此之間不能相互攻擊(不同行,不同列,不同對角線)。給定...
    Alfie20閱讀 626評論 0 0
  • 偷懶是阻礙人類的重要障礙。 你問偷懶爽嗎?我說當然爽啊。偷懶我可以干我想干的事,要完成的任務什么的一邊去,無憂無慮...
    羽生太一閱讀 411評論 0 0