ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 5589|回复: 9

[分享] vba实现解数独题目

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-8-14 10:28 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
直接上代码
  1. 模块
复制代码
主程序
  1. Sub MainStart()
  2. Dim Kcell, Row, Col, k As Integer 'Kcell-非空单元格个数,等于81时表示填写完毕
  3. Dim Result As Boolean
  4. Kcell = 1
  5. Sheet3.Range("E1").Value = 1 '记录缓存队列的位置
  6. Sheet3.Range("E2") = 0 '此格子的数字表示是否有过缓存。0没有,1有
  7. SetFontColor '设置原有内容的颜色
  8. Sheet3.Range("A:C").ClearContents
  9. t = Timer

  10. For Row = 1 To 9 '逐个格子进行循环,行
  11.     For Col = 1 To 9 '逐个格子进行循环,列
  12.         If Sheet1.Cells(Row, Col) = "" Then '如果格子为空,则试着填入某个数字
  13.             Result = RC_RANGE(Row, Col, 1) '返回结果为真,表示可填写
  14.             If Result Then '结果为真,判断是否完成解题
  15.                 Kcell = WorksheetFunction.CountA(Range("A1:I9")) '获取非空单元格个数
  16.                 If Kcell = 81 Then
  17.                     MsgBox "解题完成,耗时:" & Timer - t
  18.                 End If
  19.                 If Sheet3.Range("E1").Value = 1 And Sheet3.Range("E2").Value = 1 And Sheet3.Range("A1") = "" Then
  20.                     MsgBox "此数独无解!"
  21.                     End
  22.                 End If
  23.                 k = Sheet3.Range("E1").Value - 1
  24.                 Row = Sheet3.Cells(k, 1)
  25.                 Col = Sheet3.Cells(k, 2)
  26.             Else '返回结果假则无解
  27.                 MsgBox "此数独无解!"
  28.             End If
  29.         End If
  30.     Next Col
  31. Next Row
  32. End Sub

  33. Sub SetFontColor() '设置字体颜色

  34. Dim i, j As Integer

  35. i = j = 1

  36. Sheet1.Range("a1:i9").Font.Color = vbBlack '设置字体为黑色

  37. For i = 1 To 9

  38.     For j = 1 To 9
  39.         
  40.         If Sheet1.Cells(i, j) <> "" Then
  41.         
  42.             Sheet1.Cells(i, j).Font.Color = vbRed '设置字体为红色
  43.             
  44.         End If
  45.         
  46.     Next
  47.    
  48. Next

  49. End Sub
复制代码


数独算法.zip

30.42 KB, 下载次数: 423

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-8-14 10:30 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. Function RC_RANGE(ByVal r As Integer, ByVal c As Integer, ByVal p As Integer) As Boolean '判断是否可填入数字,p为将要填写的数字
  2. Dim a1, a2, a3 As Integer
  3. Dim Result1 As Boolean
  4. a1 = 0 '标记宫是否可填入
  5. a2 = 0 '标记r行是否可填入
  6. a3 = 0 '标记宫c列否可填入
  7. '1
  8. If 1 <= r And r <= 3 And 1 <= c And c <= 3 Then '1宫
  9.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("A1:C3"), p)
  10.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  11.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  12.     If (a1 + a2 + a3) = 0 Then
  13.         RC_RANGE = True
  14.     Else
  15.         RC_RANGE = False
  16.     End If
  17. End If
  18. '2
  19. If 1 <= r And r <= 3 And 4 <= c And c <= 6 Then '2宫
  20.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("D1:F3"), p)
  21.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  22.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  23.     If (a1 + a2 + a3) = 0 Then
  24.         RC_RANGE = True
  25.     Else
  26.         RC_RANGE = False
  27.     End If
  28. End If
  29. '3
  30. If 1 <= r And r <= 3 And 7 <= c And c <= 9 Then '3宫
  31.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("G1:I3"), p)
  32.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  33.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  34.     If (a1 + a2 + a3) = 0 Then
  35.         RC_RANGE = True
  36.     Else
  37.         RC_RANGE = False
  38.     End If
  39. End If
  40. '4
  41. If 4 <= r And r <= 6 And 1 <= c And c <= 3 Then '4宫
  42.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("A4:C6"), p)
  43.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  44.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  45.     If (a1 + a2 + a3) = 0 Then
  46.         RC_RANGE = True
  47.     Else
  48.         RC_RANGE = False
  49.     End If
  50. End If
  51. '5
  52. If 4 <= r And r <= 6 And 4 <= c And c <= 6 Then  '5宫
  53.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("D4:F6"), p)
  54.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  55.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  56.     If (a1 + a2 + a3) = 0 Then
  57.         RC_RANGE = True
  58.     Else
  59.         RC_RANGE = False
  60.     End If
  61. End If
  62. '6
  63. If 4 <= r And r <= 6 And 7 <= c And c <= 9 Then '6宫
  64.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("G4:I6"), p)
  65.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  66.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  67.     If (a1 + a2 + a3) = 0 Then
  68.         RC_RANGE = True
  69.     Else
  70.         RC_RANGE = False
  71.     End If
  72. End If
  73. '7
  74. If 7 <= r And r <= 9 And 1 <= c And c <= 3 Then  '7宫
  75.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("A7:C9"), p)
  76.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  77.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  78.     If (a1 + a2 + a3) = 0 Then
  79.         RC_RANGE = True
  80.     Else
  81.         RC_RANGE = False
  82.     End If
  83. End If
  84. '8
  85. If 7 <= r And r <= 9 And 4 <= c And c <= 6 Then '8宫
  86.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("D7:F9"), p)
  87.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  88.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  89.     If (a1 + a2 + a3) = 0 Then
  90.         RC_RANGE = True
  91.     Else
  92.         RC_RANGE = False
  93.     End If
  94. End If
  95. '9
  96. If 7 <= r And r <= 9 And 7 <= c And c <= 9 Then '9宫
  97.     a1 = Application.WorksheetFunction.CountIf(Sheet1.Range("G7:I9"), p)
  98.     a2 = Application.WorksheetFunction.CountIf(Sheet1.Range("A" & r & ":" & "I" & r), p)
  99.     a3 = Application.WorksheetFunction.CountIf(Sheet1.Range(Mid(Cells(r, c).Address, 2, 1) & "1" & ":" & Mid(Cells(r, c).Address, 2, 1) & "9"), p)
  100.     If (a1 + a2 + a3) = 0 Then
  101.         RC_RANGE = True
  102.     Else
  103.         RC_RANGE = False
  104.     End If
  105. End If
  106. Result1 = RC_RANGE

  107. '判断返回的结果,如果结果为假,说明当前数字不可填入,继续填写下一个数字直到9
  108. '如果结果为真,则填入当前数字,并在sheet2中记录当前单元格的行列和填写的值
  109. '如果到9也不可填入,说明无解
  110. If Result1 = False Then '如果结果为假,即当前数字不可填入,则数字p加1,回调直到9为止
  111.     p = p + 1
  112.     'If p = 10 Then '说明没有数字可以填写,让程序返回上一个格子重新填写
  113.         'RC_RANGE = False
  114.         'Exit Function
  115.         'Sheet3.Range("E1").Value = Sheet3.Range("E1").Value - 1
  116.         'm = Sheet3.Range("E1").Value
  117.         'r = Sheet3.Cells(m, 1)
  118.         'c = Sheet3.Cells(m, 2)
  119.         'p = Sheet3.Cells(m, 3)
  120.         'Sheet3.Range("a" & p & ":" & "c" & p).ClearContents '清除当前缓存队列
  121.         'Sheet1.Cells(r, c).ClearContents
  122.         'If m = 1 And Sheet3.Range("E2").Value = 1 Then
  123.         '    Result1 = False
  124.         '    Exit Function
  125.         'End If
  126.         'Result1 = RC_RANGE(r, c, p + 1) '此处p可能会增加到10,需要判断此类情况
  127.     'End If
  128.     Result1 = RC_RANGE(r, c, p)
  129. ElseIf Result1 = True And p <> 10 Then '结果为真,填写数字并记录行列和值的信息,并结束次过程,并返回结果真,让住程序填写下一个格子
  130.     Sheet1.Cells(r, c) = p '填写数字
  131.     Sheet3.Cells(Sheet3.Range("E1").Value, 1) = r '记录行
  132.     Sheet3.Cells(Sheet3.Range("E1").Value, 2) = c '记录列
  133.     Sheet3.Cells(Sheet3.Range("E1").Value, 3) = p '记录填写的值
  134.     Sheet3.Range("E1") = Sheet3.Range("E1").Value + 1
  135.     Sheet3.Range("E2") = 1
  136.     'RC_RANGE = True
  137.     Exit Function
  138. ElseIf Result1 = True And p = 10 Then '在第一次为假的时候,可能P会加到10,所以要判断这种情况
  139.     Sheet3.Range("E1").Value = Sheet3.Range("E1").Value - 1
  140.     m = Sheet3.Range("E1").Value
  141.     r = Sheet3.Cells(m, 1)
  142.     c = Sheet3.Cells(m, 2)
  143.     p = Sheet3.Cells(m, 3)
  144.     Sheet3.Range("a" & m & ":" & "c" & m).ClearContents '清除当前缓存队列
  145.     Sheet1.Cells(r, c).ClearContents
  146.     If m = 1 And Sheet3.Range("E2").Value = 1 Then
  147.         Result1 = False
  148.         Exit Function
  149.     End If
  150.     Result1 = RC_RANGE(r, c, p + 1)
  151. End If
  152. RC_RANGE = Result1
  153. End Function
复制代码

发现模块的代码没贴上,现在重贴

TA的精华主题

TA的得分主题

发表于 2019-2-16 23:27 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-2-17 14:48 | 显示全部楼层
这道题算到卡死都没解开

解不开

解不开

TA的精华主题

TA的得分主题

发表于 2019-2-17 14:51 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 micch 于 2019-2-17 19:20 编辑

真厉害2015年的帖子,没人回,2019年翻出来了
哪位数学好的做一下,我做了一下午,最后只能遍历去解题,发现楼上是无解的,但不知道如何证明

TA的精华主题

TA的得分主题

发表于 2019-2-18 20:04 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 ryueifu2 于 2019-2-18 20:23 编辑

大家可以计算一下这道题
..53.....8......2..7..1.5..4....53...1..7...6..32...8..6.5....9..4....3......97..

我在六七年前上传了一个文档,里面全是数独题目,大家下载看看:
https://wenku.baidu.com/view/d149d91cfc4ffe473368ab23.html

TA的精华主题

TA的得分主题

发表于 2019-2-18 20:11 | 显示全部楼层
我也分享一个数独求解和生成工具:

数独自动求解工具(刘永富).rar

19.61 KB, 下载次数: 254

TA的精华主题

TA的得分主题

发表于 2019-2-18 20:18 | 显示全部楼层
本帖最后由 ryueifu2 于 2019-2-18 20:19 编辑
huanghai22 发表于 2019-2-17 14:48
这道题算到卡死都没解开

你这道题的答案是:
1.png

TA的精华主题

TA的得分主题

发表于 2019-2-26 15:23 | 显示全部楼层
ryueifu2 发表于 2019-2-18 20:11
我也分享一个数独求解和生成工具:

暴力解法有点慢,vb的话应该毫秒级,c语言的话应该微妙级

TA的精华主题

TA的得分主题

发表于 2020-3-1 12:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
有道数独,楼上的VB给出无解的执行结果,那个工具解出来,谢谢大神。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-26 23:56 , Processed in 0.036910 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表