九宮格問題(回溯法,Go語言實現)
問題重現:
有1~10十個數,填入9個數到九宮格,現要求相鄰(上下、左右)的兩數之和為質數,問有多少種填法?
此題比較簡單,所以直接給代碼了。
解法一
package mainimport ("fmt")var pos [9]intvar sub []int = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}var num []int = []int{1, 2, 3, 5, 7, 11, 13, 17, 19}/*從質數中尋找,找到返回true*/func searchFromNum(n int) bool {for i := 0; i < 9; i++ {if n == num[i] {return true}}return false}/*檢驗結果是否正確*/func check(i, n int) bool {//縱向if i-3 >= 0 {if searchFromNum(pos[i]+pos[i-3]) == false {return false}}//橫向if i%3 != 0 {if searchFromNum(pos[i]+pos[i-1]) == false {return false}}return true}var down, up int = 0, 9/*填入1~10到九宮格的解,回溯法*/func fillBox(i, n, r int, count *int) {if i == n {(*count)++for i := 0; i < r; i++ {for j := 0; j < r; j++ {fmt.Printf("%3d", pos[i*r+j])}fmt.Println()}fmt.Println("============")return}for j := down; j <= up; j++ {//先放入pos[i] = sub[j]if sub[j] != -1 && check(i, n) {sub[j] = -1fillBox(i+1, n, r, count)sub[j] = pos[i]}}}func main() {count := 0fillBox(0, 9, 3, &count)fmt.Println(count)}
解法二
package mainimport ("fmt")var pos [9]intvar sub []int = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}var num []int = []int{1, 2, 3, 5, 7, 11, 13, 17, 19}/*從質數中尋找,找到返回true*/func searchFromNum(n int) bool {for i := 0; i < 9; i++ {if n == num[i] {return true}}return false}/*檢驗結果是否正確*/func check(n int) bool {//行相鄰for i := 0; i < n; i++ {for j := 0; j < n-1; j++ {if searchFromNum(pos[i*n+j]+pos[i*n+j+1]) == false {return false}}}//列相鄰for j := 0; j < n; j++ {for i := 0; i < n-1; i++ {if searchFromNum(pos[i*n+j]+pos[(i+1)*n+j]) == false {return false}}}return true}var down, up int = 0, 9/*填入0~8到九宮格的解,全排列(枚舉)*/func fillBox(i, n, r int, count *int) {if i == n {if check(r) {(*count)++for i := 0; i < r; i++ {for j := 0; j < r; j++ {fmt.Printf("%3d", pos[i*r+j])}fmt.Println()}fmt.Println("============")}return}for j := down; j <= up; j++ {if sub[j] != -1 {pos[i] = sub[j]sub[j] = -1fillBox(i+1, n, r, count)sub[j] = pos[i]}}}func main() {count := 0fillBox(0, 9, 3, &count)fmt.Println(count)}