ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] 做题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-7-18 10:03 | 显示全部楼层 |阅读模式
引自挑战号称世界第一的凑数算法-Excel VBA程序开发-ExcelHome技术论坛 -王守恩坛友,



给出一个正整数n,将获得数组(0,1,1,2,2,…,n,n),
即1至n每个数字有2个,0只有一个。
排列这些数字,使得两个 k 中间有 k 个数(k=1,2,…,n),
譬如。
1有1种排法: ("101")---两个1中间有1个数字(0);
2有1种排法:  ("12102")---1和1中间有1个数字(2),2和2之间有2个(10)
3有1种排法:("1312032")
4有3种排法:("131423024" "141302432" "240231413")
5有11种排法

我们约定:第1个数(不能是0)小于或等于最后1个数。
得到一串数:1, 1, 1, 3, 11, 38, 130, 638, 4158, 23384, 124520, 847484, 6987380,......


以下给出一个粗糙的递归解法。
但递归毕竟效率有点低,有兴趣的朋友可以试试其他算法。


Dim ar, m, r, d, br
Sub main()
t = Timer
Set d = VBA.CreateObject("scripting.dictionary")
Sheet1.UsedRange.Offset(1).ClearContents
n = Range("c1").Value '获得数字n
m = 2 * n + 1 '数组长度
r = 1
ReDim ar(1 To m) '数组ar存放结果
'ReDim br(1 To 999999, 1 To m)

Call zh(1, n) '开始递归排列

Range("i1") = r - 1
'Range("a2").Resize(r, m) = br
MsgBox Timer - t & "s"
End Sub
Sub zh(startw, n) 'startw是开始位置

If startw > m Then '位置到底末尾,输出结果
    If ar(m) >= ar(1) Then
        r = r + 1
        Cells(r, 1).Resize(1, m) = ar
'        For j = 1 To m
'            br(r, j) = ar(j)
'        Next
    End If
    Exit Sub
End If

If ar(startw) <> "" Then '如何startw位置不为空,递归下一位置
    Call zh(startw + 1, n)
    Exit Sub
End If

For i = IIf(startw = 1, 1, 0) To n '试填数字0-n
    nextw = IIf(i = 0, startw, startw + i + 1)
    If Not d.exists(i) And nextw <= m Then
        If ar(nextw) = "" Then
            ar(startw) = i
            ar(nextw) = i
            d(i) = ""
                        
            Call zh(startw + 1, n) '递归
            ar(startw) = "" '回溯
            ar(nextw) = ""
            d.Remove i
        End If
    End If
Next

End Sub


排数字.zip (20.6 KB, 下载次数: 10)

评分

1

查看全部评分

头像被屏蔽

TA的精华主题

TA的得分主题

发表于 2024-7-18 14:16 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-7-18 20:32 | 显示全部楼层
时间的音符 发表于 2024-7-18 14:16
很早以前做过这题了.以前是暴力做的.其实可以记忆化搜索(等价动态规划).
算到第14个是我电脑极限了.

老师应是本论坛继香大师后的算法大师啊,太强大了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-18 21:50 | 显示全部楼层
本帖最后由 yynrzwh 于 2024-7-18 21:58 编辑

我的电脑算个11都要35秒,12要317秒,5分多!

TA的精华主题

TA的得分主题

发表于 2024-7-19 12:56 | 显示全部楼层
本帖最后由 nihao123456789 于 2024-7-19 14:21 编辑

捣鼓了好久,刷新速度缩短到了1/4以下,甚感欣慰。。。
笔记本电脑性能不行请无视,楼主的64秒,我的14秒
2a32b5c4a479f909247d56af03b38f1.png
eb9edbd05a876724c95c46acf71e3d9.png

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-7-19 15:11 | 显示全部楼层
nihao123456789 发表于 2024-7-19 12:56
捣鼓了好久,刷新速度缩短到了1/4以下,甚感欣慰。。。
笔记本电脑性能不行请无视,楼主的64秒,我 ...

老大,我那个分组的问题方便抽空玩玩吗https://club.excelhome.net/threa ... tml?_dsign=92782fb6

TA的精华主题

TA的得分主题

发表于 2024-7-19 16:35 | 显示全部楼层
只做了个位数3~9的,10以上就需要换方法了
  1. Dim n0, k0
  2. Sub Main2()
  3.     n0 = 9 ' n0=:3~9
  4.     For i = 0 To n0: s = s & i: Next
  5.     k0 = 0
  6.     DFS2 String(n0 * 2 + 1, "x"), s
  7.     Cells(2, n0).Value = k0
  8. End Sub
  9. Sub DFS2(s0, t0)
  10.     If InStr(s0, "x") > 0 Then
  11.         If Len(Replace(s0, "x", "")) = 0 Then t1 = Replace(t0, 0, "") Else t1 = t0
  12.         For i = 1 To Len(t1)
  13.             l = InStr(s0, "x"): t2 = Mid(t1, i, 1)
  14.             If t2 = "0" Then
  15.                     DFS2 Replace(s0, "x", 0, , 1), Replace(t0, 0, "")
  16.             ElseIf Mid(s0, l + t2 + 1, 1) = "x" Then
  17.                     DFS2 Left(s0, l - 1) & t2 & Mid(s0, l + 1, t2) & t2 & Mid(s0, l + t2 + 1 + 1), Replace(t0, t2, "")
  18.             End If
  19.         Next
  20.     Else
  21.         If Mid(s0, 1, 1) < Right(s0, 1) Then k0 = k0 + 1
  22.     End If
  23. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-19 17:19 | 显示全部楼层
micch 发表于 2024-7-19 16:35
只做了个位数3~9的,10以上就需要换方法了

老师果然有奇思妙想,竟然想到用字符串的方法。

TA的精华主题

TA的得分主题

发表于 2024-7-20 10:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 ynzsvt 于 2024-7-20 10:12 编辑

3        1        2        1        3        2        0
1        3        1        2        0        3        2


好像3有两组答案!

TA的精华主题

TA的得分主题

发表于 2024-7-20 10:18 | 显示全部楼层
3有两种答案,如果逆顺序也算,4种答案。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-18 14:36 , Processed in 0.040651 second(s), 18 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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