ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] VBA语言编写自然数排成一圈后为素数

[复制链接]

TA的精华主题

TA的得分主题

发表于 2016-4-19 09:19 | 显示全部楼层 |阅读模式


VBA语言编写自然数排成一圈后为素数


将1,2,3,...,20这20个连续的自然数排成一圈,使任意两个相邻的自然数之和均为素数

TA的精华主题

TA的得分主题

发表于 2016-4-19 14:38 | 显示全部楼层
你不如告诉大家,用什么思路来排,然后大师们就会给你写了,否则,你觉得有人闲没事给你算一下他们之和是不是素数?

TA的精华主题

TA的得分主题

发表于 2016-4-19 16:49 | 显示全部楼层
满足条件的解有很多啊。

第1组:
1        2        3        4        7        6        5        8        9        10        13        16        15        14        17        20        11        12        19        18

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-4-19 16:59 | 显示全部楼层
  1. Dim a&(3, 9), b(19), c(3 To 39) As Boolean, k&
  2. Sub 排列组合检查圆圈相邻数相加为素数()
  3.     tms = Timer
  4.     sr = [{3,5,7,11,13,17,19,23,29,31,37}] '1-20个数相加为素数的集合
  5.     For i = 1 To 10
  6.         a(2, i - 1) = i * 2: a(3, i - 1) = i * 2 - 1 '数据填充
  7.         c(sr(i)) = True '2个数相加为素数的标记数组
  8.     Next
  9.     a(1, 0) = 1: b(0) = 1: c(37) = True '起始数为=1
  10.    
  11.     k = 0: Call dgPL(0, 1) '递归检查排列组合
  12.     MsgBox Format(Timer - tms, "0.000s ") & k
  13. End Sub

  14. Sub dgPL(i&, t&)
  15.     Dim j&
  16.     If t = 20 Then If c(b(19) + 1) Then k = k + 1: Cells(k, 1).Resize(, 20) = b: If k > 100 Then End
  17.     '满足20个排列组合数以后检查最后1个数 符合则输出结果。 满100就退出。

  18.     For j = 0 To 9 '遍历奇数或偶数
  19.         If a(i, j) = 0 Then '如该数未使用
  20.             If c(b(t - 1) + a(i + 2, j)) Then '且相邻数相加为素数
  21.                 a(i, j) = 1: b(t) = a(i + 2, j)  '则记录有效
  22.                 Call dgPL(IIf(i, 0, 1), t + 1)   '递归继续
  23.                 a(i, j) = 0: b(t) = "" '深入递归无效时递归返回并清空
  24.             End If
  25.         End If
  26.     Next
  27. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-4-20 09:21 | 显示全部楼层
经过计算验证,1-20共有6,309,300种排列组合满足要求。


  1. Dim a&(), b(), c() As Boolean, k&, n&, cnt&
  2. Sub 圆圈相邻数相加为素数的排列计算()
  3.     Dim i&, tms#
  4.     [a1].CurrentRegion = ""
  5.     tms = Timer
  6.     n = 10 '此处n为数字范围的一半即奇偶个数 n=10的实际范围为1-20
  7.     ReDim a(3, n - 1), b(2 * n - 1)
  8.     For i = 1 To n
  9.         a(2, i - 1) = i * 2: a(3, i - 1) = i * 2 - 1
  10.     Next
  11.     a(1, 0) = 1: b(0) = 1: c = GetPrime(4 * n - 1)
  12.    
  13.     k = 0: cnt = 0: Call dgPL(0, 1)
  14.     Cells(n, 27) = 2 * n: Cells(n, 28) = k: Cells(n, 29) = cnt: Cells(n, 30) = Format(Timer - tms, "0.000s")
  15.     MsgBox Format(Timer - tms, "0.000s ") & k & "/" & cnt
  16. End Sub
  17. Sub dgPL(i&, t&)
  18.     Dim j&
  19.     cnt = cnt + 1
  20.     If t = 2 * n Then If c(b(2 * n - 1) + 1) Then k = k + 1: If k < 11 Then Cells(k, 1).Resize(, 2 * n) = b
  21.     For j = 0 To n - 1
  22.         If a(i, j) = 0 Then
  23.             If c(b(t - 1) + a(i + 2, j)) Then
  24.                 a(i, j) = 1: b(t) = a(i + 2, j)
  25.                 Call dgPL(IIf(i, 0, 1), t + 1)
  26.                 a(i, j) = 0: b(t) = ""
  27.             End If
  28.         End If
  29.     Next
  30. End Sub
  31. Function GetPrime(n&) '计算素数数列
  32.     Dim a&(), b() As Boolean, i&, j&, k&, m&, s&
  33.     m = n \ 2: ReDim a&(m), b(3 To n) As Boolean
  34.     For i = 1 To Sqr(n) \ 2
  35.         If a(i) = 0 Then
  36.             s = i * 2 + 1: b(s) = True: k = k + 1: a(k) = s
  37.             For j = (i * 3 + 1) To m Step s
  38.                 a(j) = 1
  39.             Next
  40.         End If
  41.     Next
  42.     For i = (a(k) + 1) / 2 To m
  43.         If a(i) = 0 Then s = i * 2 + 1: b(s) = True ': k = k + 1: a(k) = s
  44.     Next
  45.     GetPrime = b
  46. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-4-25 12:47 | 显示全部楼层
经确认,直接对1-n进行排列计算,反而比楼上区分奇偶性的算法更快!

代码也简单:
  1. Dim a() As Boolean, b%(), c() As Boolean, k&, n%, cnt&
  2. Sub prime排列1() ' m*m prime
  3.     Dim tms#
  4. '    [a:z] = ""
  5.     tms = Timer
  6.    
  7.     n = 16
  8.     ReDim a(1 To n), b(n - 1)
  9.     a(1) = True: b(0) = 1
  10.     c = GetPrime(2 * n - 1)
  11.    
  12.     k = 0: cnt = 0: Call dgPL1(1)
  13.     MsgBox Format(Timer - tms, "0.000s ") & k & "/" & cnt
  14. End Sub
  15. Sub dgPL1(t%)
  16.     Dim i%, i1%, j1%, f As Boolean
  17.     cnt = cnt + 1
  18. '    If t = n Then If c(b(t - 1) + 1) Then k = k + 1: Cells(k, 1).Resize(, n) = b: Stop
  19.     If t = n Then If c(b(t - 1) + 1) Then k = k + 1: Exit Sub
  20.    
  21.     For i = 1 To n
  22.         If Not a(i) Then If c(b(t - 1) + i) Then a(i) = True: b(t) = i: Call dgPL1(t + 1): a(i) = False
  23.     Next
  24. End Sub
  25. Function GetPrime(n&)
  26.     Dim a&(), b() As Boolean, i&, j&, k&, m&, s&
  27.     m = n \ 2: ReDim a&(m), b(3 To n) As Boolean
  28.     For i = 1 To Sqr(n) \ 2
  29.         If a(i) = 0 Then
  30.             s = i * 2 + 1: b(s) = True: k = k + 1: a(k) = s
  31.             For j = s + i To m Step s
  32.                 a(j) = 1
  33.             Next
  34.         End If
  35.     Next
  36.     For i = (a(k) + 1) / 2 To m
  37.         If a(i) = 0 Then s = i * 2 + 1: b(s) = True ': k = k + 1: a(k) = s
  38.     Next
  39.     GetPrime = b
  40. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-4-27 21:10 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
香川群子 发表于 2016-4-25 12:47
经确认,直接对1-n进行排列计算,反而比楼上区分奇偶性的算法更快!

代码也简单:

高手中的高手
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-28 13:45 , Processed in 0.042716 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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