九宮格問題(回溯的多種寫法,Go語言實現)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

九宮格問題(回溯法,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)}

回溯非遞迴解法:

package mainimport ("fmt")var num [9]int = [9]int{1, 2, 3, 5, 7, 11, 13, 17, 19}var pos [9]int //存放連續的1~10var sum, down, up, r int = 9, 0, 10, 3func backTrack() int {sum--isNoConflict := true //預設true無衝突count := 0           //統計數0i := 0pos[0] = 1 //起始值是從1開始for {if isNoConflict {if i == sum {count++for i := 0; i < r; i++ {for j := 0; j < r; j++ {fmt.Printf("%3d", pos[i*r+j])}fmt.Println()}for pos[i] == up {i--if i == -1 {return count}//此時的i佔據的值根本就沒有參與check(),所以值是多少並不重要了,也就等於撤銷了之前的佔用}pos[i]++} else {i++pos[i] = 1 //起始值是從1開始}} else {//發生衝突for pos[i] == up {i--if i == -1 {return count}//此時的i佔據的值根本就沒有參與check(),所以值是多少並不重要了,也就等於撤銷了之前的佔用}pos[i]++}isNoConflict = check(i)}}func main() {fmt.Println(backTrack())}/*檢驗結果是否正確*/func check(i int) bool {//搜尋當前值是否已在前面使用過了for j := 0; j < i; j++ {if pos[j] == pos[i] {return false}}//縱向  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}/*從質數中尋找,找到返回true*/func searchFromNum(n int) bool {for i := 0; i < 9; i++ {if n == num[i] {return true}}return false}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.