四阶幻方就是用16个数字组成的一个四行四列的矩阵,其每一行、每一列和两条对角线的数字的和(称为幻和值)都相等。
暴力解法如下:
package main
import (
"fmt"
"time"
)
var order = 4 // 矩阵行列数
var sum = 34 // 总和
var Arr1 = [17]int{} // 存放全排列结果
var c = 0 // 执行次数
var total = 0 // 种数
var Arr2 = [17]int{} // 数组,用作判断1-16个数是否有被访问到
func main() {
start := time.Now() // 开始时间
test(0)
fmt.Println("执行次数:", c)
end := time.Now().Sub(start) // 结束时间
fmt.Println("总耗时:", end)
}
func test(x int) {
c++
if x == 15 {
t1 := sum - (Arr1[12] + Arr1[13] + Arr1[14]) // 行
t2 := sum - (Arr1[3] + Arr1[7] + Arr1[11]) // 列
t3 := sum - (Arr1[0] + Arr1[5] + Arr1[10]) // 另一个对角线
// 满足横竖斜加起来都等于34
if t1 == t2 && t2 == t3 && Arr2[t1] == 0 { // 最后来个总的判断,如果满足条件,则打印
Arr1[x] = t1
total++
fmt.Printf("第%v种:\n", total)
lastArr := Arr1[:16]
for k, v := range lastArr {
if k == 4 || k == 8 || k == 12 || k == 16 {
fmt.Println()
}
fmt.Print(" ", v)
}
fmt.Println()
}
Arr2[Arr1[x-1]] = 0
return
}
// 做判断
if x > 0 && x%4 == 0 && Arr1[(x/order-1)*order]+Arr1[(x/order-1)*order+1]+Arr1[(x/order-1)*order+2]+Arr1[(x/order-1)*order+3] != sum {
Arr2[Arr1[x-1]] = 0
return
}
// 中心剪枝
if x == 11 && Arr1[5]+Arr1[6]+Arr1[9]+Arr1[10] != sum {
Arr2[Arr1[x-1]] = 0
return
}
// 对角线剪枝和边行剪枝,加快速度
if x == 13 && (Arr1[3]+Arr1[6]+Arr1[9]+Arr1[12] != sum || Arr1[4]+Arr1[8]+Arr1[7]+Arr1[11] != sum) {
Arr2[Arr1[x-1]] = 0
return
}
// 列剪枝
if (x == 13 || x == 14) && Arr1[x-13]+Arr1[x-13+4]+Arr1[x-13+8]+Arr1[x-13+12] != sum {
Arr2[Arr1[x-1]] = 0
return
}
for i := 1; i <= 16; i++ { // 生成全排列
if Arr2[i] == 0 { // 访问当前没有用到的数字
Arr1[x] = i
Arr2[i] = 1
// 递归
test(x + 1)
Arr2[i] = 0 //回溯时复原Arr2数组
}
}
}
结果: