频道栏目
首页 > 资讯 > 其他 > 正文

用两种方法求解九宫算问题

18-06-29        来源:[db:作者]  
收藏   我要投稿

问题:

在一个3*3的方格内填入9个数字,数字的范围从1~9,每个数字仅出现一次,使得每行、每列以及两个对角线的数字之和为15。

一、VBA程序

算法思路:

1、将9个数字分成3组,每组3个数字,使得每组数字之和为15。

2、将第二个数字为5个分组单独选出,作为方格的第二行数组。

3、循环抽取其它的分组,与第二分组进行重复性判断。

4、如果没有重复,记录这3种分组。

5、将这3种分组传人判断函数,核实是否满足条件。

6、如果满足条件,将结果输出。

VBA源程序如下:

运行结果

6 7 2

Sub jiugongsuan_All()

Dim cs(1 To 9) As Integer
Dim jgs1(1 To 3) As Integer
Dim Ot() As Integer
'第一、三行数组
Dim Sec() As Integer
'第二行数组
Dim temp1(1 To 100, 1 To 3) As Integer
Dim temp2(1 To 100, 1 To 3) As Integer
'temp1、temp2分别为临时数组
Dim Totali As Integer
'第二个数为5,三个数之和为15的数组个数
Dim Totaln As Integer
'不包括第二个数为5,三个数之和为15的数组个数
Dim at(1 To 3) As Integer
Dim bt(1 To 3) As Integer
Dim ct(1 To 3) As Integer
'at、bt、ct分别为中间变量数组

Dim scjg(1 To 3, 1 To 3) As Integer
'scjg为结果数组


Dim i As Integer

Totali = 0
Totaln = 0

For i = 1 To 9
'初始数组赋值
cs(i) = i

Next

For m = 1 To 9
 If cs(m) <> 0 Then
'判断该数字是否已被占用
jgs1(1) = cs(m)
cs(m) = 0
'占用该数字
 
For n = 1 To 9
 If cs(n) <> 0 Then
 jgs1(2) = cs(n)
  cs(n) = 0
  
For q = 1 To 9
  If cs(q) <> 0 Then
jgs1(3) = cs(q)
 cs(q) = 0
  
 
If jgs1(1) + jgs1(2) + jgs1(3) = 15 Then

 ' Debug.Print jgs1(1); jgs1(2); jgs1(3)
  
If jgs1(2) = 5 Then
'第二行数据
  Totali = Totali + 1
 temp1(Totali, 1) = jgs1(1)
 temp1(Totali, 2) = jgs1(2)
 temp1(Totali, 3) = jgs1(3)
Else
' 第一行,第三行数据
  Totaln = Totaln + 1
 temp2(Totaln, 1) = jgs1(1)
 temp2(Totaln, 2) = jgs1(2)
 temp2(Totaln, 3) = jgs1(3)
  

  
  End If
  
  
  
 End If

cs(q) = q
End If
 
 Next
 
cs(n) = n
 End If
 
 
 Next
  
  cs(m) = m
 End If
 

 
Next

ReDim Sec(1 To Totali, 1 To 3)
ReDim Ot(1 To Totaln, 1 To 3)


For m1 = 1 To Totali
Sec(m1, 1) = temp1(m1, 1)
Sec(m1, 2) = temp1(m1, 2)
Sec(m1, 3) = temp1(m1, 3)

'第二行数组赋值

Next

For n1 = 1 To Totaln
Ot(n1, 1) = temp2(n1, 1)
Ot(n1, 2) = temp2(n1, 2)
Ot(n1, 3) = temp2(n1, 3)

Next

'第一、三行数组赋值

For m1 = 1 To Totali

 bt(1) = Sec(m1, 1)
 bt(2) = Sec(m1, 2)
 bt(3) = Sec(m1, 3)

  For n1 = 1 To Totaln
 at(1) = Ot(n1, 1)
 at(2) = Ot(n1, 2)
 at(3) = Ot(n1, 3)
 
  If cfpd(at, bt) Then
 
  
Else
 
For k1 = 1 To Totaln
 ct(1) = Ot(k1, 1)
 ct(2) = Ot(k1, 2)
 ct(3) = Ot(k1, 3)
 

If Not cfpd(at, ct) And Not cfpd(bt, ct) Then
' 第一、三行,第二、三行重复情况判断
  
scjg(1, 1) = at(1)
scjg(1, 2) = at(2)
scjg(1, 3) = at(3)
scjg(2, 1) = bt(1)
scjg(2, 2) = bt(2)
scjg(2, 3) = bt(3)
scjg(3, 1) = ct(1)
scjg(3, 2) = ct(2)
scjg(3, 3) = ct(3)

' 调用函数
 finalpd (scjg)
 
 Else
  

 End If
 
  
  
  Next
  
  End If
 
 Next

Next


End Sub

Function cfpd(a() As Integer, b() As Integer) As Boolean
'2个数组重复情况判断


 If b(1) <> a(1) And b(1) <> a(2) And b(1) <> a(3) Then
  cfpd = False
 Else
  cfpd = True
  Exit Function
  
 End If
 
 If b(2) <> a(1) And b(2) <> a(2) And b(2) <> a(3) Then
 cfpd = False
 Else
 cfpd = True
 Exit Function
 
 End If
 
 If b(3) <> a(1) And b(3) <> a(2) And b(3) <> a(3) Then
 cfpd = False
Else
 cfpd = True
 Exit Function
 
 
End If

End Function


Sub finalpd(sz As Variant)
'列求和、对角线求和判断

Dim i%, j%
Dim myjgs(1 To 3, 1 To 3)
Dim Hpd As Boolean
Dim Lpd As Boolean
Dim DJXpd As Boolean


For i = 1 To 3
 For j = 1 To 3
 myjgs(i, j) = sz(i, j)

 Next
Next


'列判断
For i = 1 To 3

If myjgs(1, i) + myjgs(2, i) + myjgs(3, i) = 15 Then
Lpd = True
Else
Lpd = False
Exit For
End If

Next

'对角线判断

If myjgs(1, 1) + myjgs(2, 2) + myjgs(3, 3) = 15 And myjgs(1, 3) + myjgs(2, 2) + myjgs(3, 1) = 15 Then
 DJXpd = True

Else
 DJXpd = False
End If


If Lpd And DJXpd Then

'结果输出

Debug.Print myjgs(1, 1); myjgs(1, 2); myjgs(1, 3)

Debug.Print myjgs(2, 1); myjgs(2, 2); myjgs(2, 3)

Debug.Print myjgs(3, 1); myjgs(3, 2); myjgs(3, 3)

Debug.Print "-------------------------"

End If


End Sub

运行结果:

6 7 2

1 5 9

8 3 4

-------------------------

83 4

15 9

67 2

-------------------------

49 2

35 7

81 6

-------------------------

81 6

35 7

49 2

-------------------------

29 4

75 3

61 8

-------------------------

6 1 8

75 3

29 4

-------------------------

27 6

95 1

43 8

-------------------------

43 8

95 1

27 6

二、EXCEL规划求解

1、选择数据菜单-à“规划求解”

2、设置可变单元格及约束条件

约束条件

行之和为15

列之和为15

所有数字均为整数

所有数字>=1

所有数字<=9

所有数字连乘的积为9的阶乘,这种方式可以限制每个数字出现1次,且仅出现1次。

图一

图二

这种方法只能求出一个解。

相关TAG标签
上一篇:FFT的小板子问题解析
下一篇:软件编程语言的几项规范
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站