N 皇后

oliver-l發表於2020-09-21

N 皇后

輸入:4
輸出:[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。

提示:

  • 皇后彼此不能相互攻擊,也就是說:任何兩個皇后都不能處於同一條橫行、縱行或斜線上。

這是一道比較經典的回溯演算法題

本題的思路通過迴圈N項,依次判斷是否可放置Q,通過hasQueen判斷縱行和左上,右上斜線是否存在Q,不存在則放置Q繼續回溯下一行放置Q位置直到N項都放滿,存在則跳過當前行列

    public $NQueens = [];
    function solveNQueens($n) {
        $arr = array_fill(0,$n,array_fill(0,$n,'.'));
        $this->flashBack($arr,$n,0);
        return $this->NQueens;
    }

    function flashBack($arr,$n,$i)
    {
        if ($i == $n){
            $tmp = [];
            foreach($arr as $item){
                $tmp[] = implode('', $item);
            }
            $this->NQueens[] = $tmp;
            return;
        }
        for ($j=0;$j<$n;$j++){
            if ($this->hasQueen($n,$arr,$i,$j)){
                continue;
            }
            //回溯
            $arr[$i][$j] = 'Q';
            $this->flashBack($arr,$n,$i+1);
            $arr[$i][$j] = '.';
        }
    }

    public function hasQueen($n,$arr,$row,$col)
    {
        // 同一行不存在衝突,無需處理
        // 左下和右下此時為空,無需處理
        // 同一列
        for ($i=0;$i<$n;$i++){
            if ($arr[$i][$col] == 'Q'){
                return true;
            }
        }
        // 右上,row - 1, col + 1
        $i = $row - 1;
        $j = $col + 1;
        for (; $i >= 0 && $j < $n; --$i, ++$j) {
            if ($arr[$i][$j] == 'Q') return true;
        }

        // 左上, row - 1, col - 1
        $i = $row - 1;
        $j = $col - 1;
        for (; $i >= 0 && $j >= 0; --$i, --$j) {
            if ($arr[$i][$j] == 'Q') return true;
        }
        return false;
    }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章