除了暴力回溯探测思想之外,还要能够掌握并使用每一条对角线与i,j下标的关系。
每一行只能有一个皇后 -> 通过每次for只给一行填一个;
每一列只能有一个皇后->通过col[n]数组来标记,哪一列放了皇后,相应的col[i] = 1;
每一 \ 这种斜列只能有一个皇后 ->总共有 dia2[2n-1] 个 \ 线,每一条线上的i,j有性质:i - j + n - 1 对于每一条 \ 总是相等的;
每一 / 这种斜列只能有一个皇后 -> 总共有dia1[2n-1] 个/ 线,每一条 / 上的个子i,j有性质:i + j对于每一条 / 上的格子总是相等的。
package main
import (
"strings"
"fmt"
)
var res [][]string
var col, dia1, dia2 []bool
func main() {
var n = int(8)
solveNQueens(n )
for i := range res {
for j := range res[i] {
fmt.Println(res[i][j])
}
fmt.Println()
}
}
func solveNQueens(n int) [][]string {
var solveRow []int
col = make([]bool, n)
dia1 = make([]bool, 2*n-1)
dia2 = make([]bool, 2*n-1)
putQueens(n, 0, solveRow )
return res
}
func putQueens(n, index int, row []int ) {
if index == n {
res = append(res, saveAsolve(n, row))
return
}
for i := 0; i < n; i++ {
if !col[i] && !dia1[index+i] && !dia2[index-i+n-1] {
row = append(row, i)
col[i] = true
dia1[index+i] = true
dia2[index-i+n-1] = true
putQueens(n, index+1, row)
col[i] = false
dia1[index+i] = false
dia2[index-i+n-1] = false
tmpLen := len(row)
row = row[:tmpLen-1]
}
}
return
}
func saveAsolve(n int, row []int) []string {
res1 := make([]string, n)
for i := range res1 {
for j := 0; j < n ; j++ {
res1[i] = strings.Repeat(".", n)
}
}
for i := 0; i < n; i++ {
tmp := res1[i]
c := []byte(tmp)
c[row[i]] = 'Q'
res1[i] = string(c)
}
return res1
}