ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[Excel 程序开发] [第96期]换硬币[已总结]

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-7-29 19:08 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 delete_007 于 2013-10-30 08:35 编辑

题目内容:
有一国,其国内硬币可按其面值至该国银行兑换,其面值为任一正整数[n],银行兑换方式为返回面值为如下的三枚:[n/2], [n/3], [n/4],当然也都取整了。另外,该银行也可用该国硬币兑换成等额的RMB。现要求编写计算器,使得输入硬币的面值(即任一正整数),而输出可获得的最大RMB数字。

例如:输入2,则可直接兑成RMB,得输出2。输入12,可先换为 [12/2]=6,[12/3]=4,[12/4]=3,再换成RMB,输出13。

答题要求:
可完形填空如下,允许添加过程或函数及公共变量:
[code=vb]Sub ChangeCoin()
    Dim aCoins(), aRes(), nCoin, t#
    ' 可更改段
    ' 只能是Dim
    ' 可更改结束
    aCoins = Array(12, 123, 1000,  50000, 600000, 30000000)
    Redim aRes(UBound(aCoins))
    t = Timer
    ' 可更改段
    For Each nCoin In aCoins
        '....
    Next
    ' 可更改结束
    Debug.Print "ID: " & "<YOUR ID>"
    Debug.Print "Result: " & Join(aRes, ", ")
    Debug.Print "Time: " & Format(Timer - t, "0.000s")
End Sub[/code]

评分规则:
1、1分钟内(超过俺就当是死机了)可获得正确结果可得1分。
2、以我的机器为准,1秒内可加1分。
3、可算10^9且低于0.1秒的可再加1分。
4、极其优秀的,超过我的预期的或可再追加1分。
5、没有按要求填空的可能会被扣1分,比如删除了原有的注释、填错了地方之类的~

知识点:
递归

提示:
可先多次换为本国硬币,再换RMB。

再以一例说明,现有面值25的硬币一枚,求最大可换回的RMB数

1、直接换得25RMB,或换得INT(25/2)=12, INT(25/3)=8, INT(25/4)=6,各一枚
2、12的硬币可直接换,得12RMB,或如前可换得6、4、3三枚硬币
      8和6的硬币也都同样有两种选择
……
如上会有多个选择分支,需要从中找出最终可得硬币面值之和最大,即为可换得的最大RMB数,此例为6+4+3+8+6=27

另3万的得数为54563,供校验。

标准答案:
不知道如何设置权限,另加~

是否参与点评与总结:
可以参与






补充内容 (2013-9-3 08:59):
总结在21楼,参考答案在32楼

点评

另外请楼主不要再编辑主题,以免“回帖仅作者可见”设置失效。  发表于 2013-7-30 14:09
竞赛日期:2013-7-30至2013-8-30  发表于 2013-7-30 14:04

评分

6

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-7-30 15:17 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 大灰狼1976 于 2013-8-3 21:30 编辑

12是个分水岭,看来我的结果是正确的,哈哈{:soso_e100:}
Sub ChangeCoin()
    Dim aCoins(), aRes(), nCoin, t#, i&, d As Object, c, n As Byte
    Set d = CreateObject("scripting.dictionary")
    ' 可更改段
    ' 只能是Dim
    ' 可更改结束
    aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
    ReDim aRes(UBound(aCoins))
    t = Timer
    ' 可更改段
    n = 0
    For Each nCoin In aCoins
      d(nCoin) = 1
      Do While Application.Max(d.keys) > 11
        For Each c In d.keys
          If c > 11 Then d(Int(c / 2)) = d(Int(c / 2)) + d(c): d(Int(c / 3)) = d(Int(c / 3)) + d(c): d(Int(c / 4)) = d(Int(c / 4)) + d(c): d.Remove (c)
        Next c
      Loop
      i = 0
      For Each c In d.keys
        i = i + c * d(c)
      Next c
      d.RemoveAll
      aRes(n) = i: n = n + 1
    Next
    ' 可更改结束
    Debug.Print "ID: " & "<YOUR ID>"
    Debug.Print "Result: " & Join(aRes, ", ")
    Debug.Print "Time: " & Format(Timer - t, "0.000s")
End Sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-7-30 15:30 | 显示全部楼层
本帖最后由 大灰狼1976 于 2013-7-30 15:32 编辑

可是我没有用递归,有简单方法为什么不用,方法应该是灵活的,开拓思维嘛

TA的精华主题

TA的得分主题

发表于 2013-8-3 11:25 | 显示全部楼层
  1. Sub ChangeCoin()
  2.     Dim aCoins(), aRes(), nCoin, t#
  3.     Dim i%              '新增语句
  4.     ' 可更改段
  5.     ' 只能是Dim
  6.     ' 可更改结束
  7. '    aCoins = Array(10 ^ 9)
  8.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  9.     ReDim aRes(UBound(aCoins))
  10.     t = Timer
  11.     ' 可更改段
  12.     For Each nCoin In aCoins
  13.         '....
  14.         aRes(i) = ExChange(CLng(nCoin))       '新增语句
  15.         i = i + 1                       '新增语句
  16.     Next
  17.     ' 可更改结束
  18.     Debug.Print "ID: " & "zhyj_88"
  19.     Debug.Print "Result: " & Join(aRes, ", ")
  20.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  21. End Sub
  22. Function ExChange(Coin As Long) As Long
  23.     Dim i%, j&, k&
  24.     For i = 2 To 4
  25.         j = Coin \ i
  26.         If j > 11 Then
  27.             k = k + ExChange(j)
  28.         Else
  29.             k = k + j
  30.         End If
  31.     Next i
  32.     ExChange = k
  33. End Function
复制代码
ID: zhyj_88
Result: 13, 144, 1370, 96394, 1427537, 98274986
Time: 2.125s



补充内容 (2013-8-10 12:52):
修改后的在10楼

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-4 14:12 | 显示全部楼层
本帖最后由 xiaofx11 于 2013-8-9 11:06 编辑

居然死机了{:soso_e101:}

  1. Sub ChangeCoin()
  2.     Dim aCoins(), aRes(), nCoin, t#, i As Long
  3.    
  4.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  5.     ReDim aRes(UBound(aCoins))
  6.     t = Timer
  7.     i = 0
  8.     For Each nCoin In aCoins
  9.         aRes(i) = xiaofx11(nCoin)
  10.         i = i + 1
  11.     Next
  12.     ' 可更改结束
  13.     Debug.Print "ID: " & "xiaofx11"
  14.     Debug.Print "Result: " & Join(aRes, ", ")
  15.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  16. End Sub

  17. Public Function xiaofx11(ByVal x As Long) As Long
  18.     If x \ 2 + x \ 3 + x \ 4 > x Then
  19.         xiaofx11 = xiaofx11(x \ 2) + xiaofx11(x \ 3) + xiaofx11(x \ 4)
  20.     Else
  21.         xiaofx11 = x
  22.     End If
  23. End Function
复制代码




补充内容 (2013-8-25 20:25):
再发一个字典的

Public Function xiaofx11(ByVal x As Long) As Long
Dim temp2, temp3, temp4
    If x \ 2 + x \ 3 + x \ 4 > x Then
        '----------
        If dic.Exists(x \ 2) Then
            temp2

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-5 16:08 | 显示全部楼层
本帖最后由 清风_ll 于 2013-8-11 22:50 编辑

理解了好几遍,确定原来的代码是对的。{:soso_e144:} 加入保存中间数值后,速度飞快啊。

  1. Dim d As Object
  2. Sub ChangeCoin()
  3.     Dim aCoins(), aRes(), nCoin, t#
  4.     ' 可更改段
  5.     ' 只能是Dim
  6.     ' 可更改结束
  7.     Dim i As Integer
  8.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  9.     ReDim aRes(UBound(aCoins))
  10.     t = Timer
  11.     ' 可更改段
  12.     Set d = CreateObject("Scripting.Dictionary")
  13.     For Each nCoin In aCoins
  14.         aRes(i) = ChangeB(nCoin)
  15.         i = i + 1
  16.     Next
  17.     ' 可更改结束
  18.     Debug.Print "ID: " & "<清风_ll>"
  19.     Debug.Print "Result: " & Join(aRes, ", ")
  20.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  21.     d.RemoveAll
  22. End Sub
  23. Function ChangeB(ByVal n As Long) As Long
  24.     Dim n1 As Long, n2 As Long, n3 As Long
  25.    
  26.     If d.Exists(CStr(n)) Then
  27.         ChangeB = d(CStr(n))
  28.         Exit Function
  29.     End If
  30.     If n >= 12 Then
  31.         n1 = Int(n / 2)
  32.         n2 = Int(n / 3)
  33.         n3 = Int(n / 4)
  34.         ChangeB = ChangeB(n1) + ChangeB(n2) + ChangeB(n3)
  35.         d.Add CStr(n), ChangeB
  36.     Else
  37.         ChangeB = n
  38.     End If
  39.    
  40. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-5 22:27 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 wcymiss 于 2013-8-6 08:52 编辑
  1. Sub ChangeCoin()
  2.     Dim aCoins(), aRes(), nCoin, t#
  3.     ' 可更改段
  4.     Dim i As Integer
  5.     ' 只能是Dim
  6.     ' 可更改结束
  7.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  8.     ReDim aRes(UBound(aCoins))
  9.     t = Timer
  10.     ' 可更改段
  11.     For Each nCoin In aCoins
  12.         aRes(i) = F(nCoin)
  13.         i = i + 1
  14.     Next
  15.     ' 可更改结束
  16.     Debug.Print "ID: " & "wcymiss"
  17.     Debug.Print "Result: " & Join(aRes, ", ")
  18.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  19. End Sub

  20. Function F(ByVal aCoins As Double) As Double
  21.     Static objDic As Object
  22.     Dim i As Integer, n As Double
  23.     If objDic Is Nothing Then Set objDic = CreateObject("scripting.dictionary")
  24.     If aCoins >= 12 Then
  25.         For i = 2 To 4
  26.             n = Int(aCoins / i)
  27.             If Not objDic.exists(n) Then objDic(n) = F(n)
  28.             F = F + objDic(n)
  29.         Next
  30.     Else
  31.         F = aCoins
  32.     End If
  33. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-7 10:42 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
不会VBA,就写个函数的方法吧,但是有局限性。欢迎指正拍砖。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-9 17:52 | 显示全部楼层
  1. Sub ChangeCoin()
  2.     Dim aCoins(), aRes(), nCoin, t#
  3.     ' 可更改段
  4.     Dim M, n& ' 只能是Dim
  5.     ' 可更改结束
  6.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  7.     ReDim aRes(UBound(aCoins))
  8.     t = Timer
  9.     ' 可更改段
  10.     For Each nCoin In aCoins
  11.         M = 0
  12.         If nCoin < 12 Then
  13.             M = nCoin
  14.         Else
  15.             Call DiGui(nCoin, M)
  16.         End If
  17.         aRes(n) = M
  18.         n = n + 1
  19.     Next
  20.     ' 可更改结束
  21.     Debug.Print "ID: " & "小花鹿"
  22.     Debug.Print "Result: " & Join(aRes, ", ")
  23.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  24. End Sub
  25. Sub DiGui(tm, M)
  26. Dim n(2 To 4), i&
  27. For i = 2 To 4
  28.     n(i) = Int(tm / i)
  29.     If n(i) < 12 Then
  30.         M = M + n(i)
  31.     Else
  32.         Call DiGui(n(i), M)
  33.     End If
  34. Next i
  35. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-8-10 11:21 | 显示全部楼层
  1. Option Explicit
  2. Dim dic As Object '新增语句
  3. Sub ChangeCoin()
  4.     Dim aCoins(), aRes(), nCoin, t#
  5.     Dim i%              '新增语句
  6.     ' 可更改段
  7.     ' 只能是Dim
  8.     ' 可更改结束
  9. '    aCoins = Array(10 ^ 9)   '新增语句
  10.     aCoins = Array(12, 123, 1000, 50000, 600000, 30000000)
  11.     ReDim aRes(UBound(aCoins))
  12.     t = Timer
  13.     ' 可更改段
  14.     Set dic = CreateObject("scripting.dictionary") '新增语句
  15.     For Each nCoin In aCoins
  16.         '....
  17.         aRes(i) = ExChange(CCur(nCoin))      '新增语句
  18.         i = i + 1                       '新增语句
  19.     Next
  20.     ' 可更改结束
  21.     Set dic = Nothing '新增语句
  22.     Debug.Print "ID: " & "zhyj_88"
  23.     Debug.Print "Result: " & Join(aRes, ", ")
  24.     Debug.Print "Time: " & Format(Timer - t, "0.000s")
  25. End Sub
  26. Function ExChange(Coin As Currency) As Currency
  27.     Dim i%, j@, k@
  28.     If dic.exists(Coin) Then ExChange = dic(Coin): Exit Function
  29.     For i = 2 To 4
  30.         j = Coin \ i
  31.         If j > 11 Then
  32.             k = k + ExChange(j)
  33.         Else
  34.             k = k + j
  35.         End If
  36.     Next i
  37.     ExChange = k: dic(Coin) = k
  38. End Function

复制代码
ID: zhyj_88
Result: 13, 144, 1370, 96394, 1427537, 98274986
Time: 0.000s

4楼无法重新编辑,只好再发一遍了。
这个应是正确答案了,因为所有数据均耗时为0秒。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

点评

评分见4楼。  发表于 2013-9-2 09:09
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-21 18:55 , Processed in 0.049130 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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