51.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. func solveNQueens(n int) (solutions [][]string) {
  7. putX := make([]int, n)
  8. colLaid := make([]bool, n)
  9. mainLaid := make([]bool, 2*n) // Range of y-x is [1-n, n-1], so y-x+n -> [1, 2n-1]
  10. viceLaid := make([]bool, 2*n-1)
  11. for y, x := 0, 0; ; { // The ith queen
  12. for ; x < n; x++ {
  13. if !(colLaid[x] || mainLaid[y-x+n] || viceLaid[x+y]) {
  14. putX[y] = x
  15. colLaid[x] = true
  16. mainLaid[y-x+n] = true
  17. viceLaid[x+y] = true
  18. x = 0 // Next step
  19. y++
  20. break
  21. }
  22. }
  23. if x == n || y == n { // Not valid or finished
  24. if y == 0 { // If y is 0 and x is n, then all solutions are found
  25. return
  26. } else if y == n {
  27. solutions = append(solutions, make([]string, 0))
  28. l := len(solutions)
  29. var sb strings.Builder
  30. for i := 0; i < n; i++ {
  31. sb.Reset()
  32. for j := 0; j < n; j++ {
  33. if putX[i] == j {
  34. sb.WriteByte('Q')
  35. } else {
  36. sb.WriteByte('.')
  37. }
  38. }
  39. solutions[l-1] = append(solutions[l-1], sb.String())
  40. }
  41. }
  42. y-- // Back tracking
  43. x = putX[y]
  44. colLaid[x] = false
  45. mainLaid[y-x+n] = false
  46. viceLaid[x+y] = false
  47. x++
  48. }
  49. }
  50. }
  51. func main() {
  52. fmt.Println(solveNQueens(9))
  53. }