Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 1359|回复: 9

[VBA] 用VBA解欧拉计划题目(32)

[复制链接]
发表于 2017-11-8 09:42 | 显示全部楼层 |阅读模式
第32题:Pandigital products
Problem 32

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
[size=14.256px]HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.



[size=14.256px]一个n位的重排数是由1-n所有数字只使用1次所组成的数。例如,15234是1-5的一个重排数。

[size=14.256px]7254是一个不一般的数字,39 × 186 = 7254,其乘数、被乘数、积,组成 了一个1-9的重排数。

[size=14.256px]求:所有乘数、被乘数、积能组成 1-9的重排数的积的和(有些积可以不同方式取得,只要计算一次)





excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
 楼主| 发表于 2017-11-8 09:43 | 显示全部楼层
第32题:Pandigital products
Problem 32

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.


一个n位的重排数是由1-n所有数字只使用1次所组成的数。例如,15234是1-5的一个重排数。
7254是一个不一般的数字,39 × 186 = 7254,其乘数、被乘数、积,组成 了一个1-9的重排数。
求:所有乘数、被乘数、积能组成 1-9的重排数的积的和(有些积可以不同方式取得,只要计算一次)
回复

使用道具 举报

发表于 2017-11-9 11:05 | 显示全部楼层
只有
a*bcde=fghi
ab*cde=fghi
这2种可能的结构吧。
回复

使用道具 举报

发表于 2017-11-9 11:10 | 显示全部楼层
4 * 1738 = 6952
4 * 1963 = 7852
12 * 483 = 5796
18 * 297 = 5346
27 * 198 = 5346
28 * 157 = 4396
39 * 186 = 7254
42 * 138 = 5796
48 * 159 = 7632
回复

使用道具 举报

发表于 2017-11-9 11:16 | 显示全部楼层
本帖最后由 香川群子 于 2017-11-9 11:17 编辑

可适当剪枝:
  1. Sub test1()
  2.     tms = Timer
  3.     For a = 3 To 5
  4.         For b = 1234 To 3000
  5.             c = a * b
  6.             If Chk(a & b & c) Then Debug.Print a; "*"; b; "="; c
  7.         Next
  8.     Next
  9.     For a = 12 To 50
  10.         For b = 123 To 500
  11.             c = a * b
  12.             If Chk(a & b & c) Then Debug.Print a; "*"; b; "="; c
  13.         Next
  14.     Next
  15.     Debug.Print Format(Timer - tms, "0.000s") & vbCr
  16. End Sub
  17. Function Chk(s) As Boolean
  18.     If Len(s) = 9 Then
  19.         For i = 1 To 9
  20.             If InStr(s, i) = 0 Then Exit Function
  21.         Next
  22.         Chk = True
  23.     End If
  24. End Function
复制代码
回复

使用道具 举报

发表于 2017-11-9 11:20 | 显示全部楼层
正确答案是41566吗?
  1. Sub aaa()
  2. Dim i&, j&, s$, c&, n&, m&
  3. For i = 10 To 100
  4.   For j = 100 To Int(98 / i) * 100 + 98
  5.     n = i * j
  6.     If n < 10000 And n > 999 Then
  7.       s = i & j & n
  8.       For c = 1 To 9
  9.         If InStr(s, c) = 0 Then Exit For
  10.       Next c
  11.       If c = 10 Then m = m + n
  12.     End If
  13.   Next j
  14. Next i
  15. MsgBox m
  16. End Sub
复制代码
回复

使用道具 举报

发表于 2017-11-9 13:19 | 显示全部楼层
大灰狼1976 发表于 2017-11-9 11:20
正确答案是41566吗?

一、漏了 a*bcde=fghi 这种类型。
即,i要从1位数开始,而不是直接从10开始。

二、原题目要求最后结果要去除重复。5346和5796有重复。

……所以最后结果,应该是=45228
回复

使用道具 举报

发表于 2017-11-9 13:20 | 显示全部楼层
香川群子 发表于 2017-11-9 13:19
一、漏了 a*bcde=fghi 这种类型。
即,i要从1位数开始,而不是直接从10开始。

是的,我试了好几种极限,但是把1位数乘4位数给漏了,低级错误
回复

使用道具 举报

发表于 2017-11-9 13:25 | 显示全部楼层
建个数组去除重复:
  1. Sub test1()
  2.     tms = Timer
  3.     ReDim d(9999) As Byte
  4.     For a = 3 To 5
  5.         For b = 1234 To 3000
  6.             c = a * b
  7.             If Len(c) = 4 Then: If Chk(a & b & c) Then If d(c) = 0 Then d(c) = 1: m = m + c ': Debug.Print a; "*"; b; "="; c
  8.         Next
  9.     Next
  10.     For a = 12 To 50
  11.         For b = 123 To 500
  12.             c = a * b
  13.             If Len(c) = 4 Then: If Chk(a & b & c) Then If d(c) = 0 Then d(c) = 1: m = m + c ': Debug.Print a; "*"; b; "="; c
  14.         Next
  15.     Next
  16.     Debug.Print m; Format(Timer - tms, "0.000s") & vbCr
  17. End Sub
  18. Function Chk(s) As Boolean
  19. '    If Len(s) = 9 Then
  20.     For i = 1 To 9
  21.         If InStr(s, i) = 0 Then Exit Function
  22.     Next
  23.     Chk = True
  24. '    End If
  25. End Function
复制代码
回复

使用道具 举报

 楼主| 发表于 2017-11-9 13:47 | 显示全部楼层
贴上我的代码。
  1. Sub problem32()  'a*b=c,要求abc为1-9的pandigit ,计算所有c的和,相同的c只计算一次。。。结果是45228
  2. '分析易知只有两种情况,1位*4位=4位,2位*3位=5位
  3. Set d = CreateObject("scripting.dictionary")
  4. For k = 1 To 2
  5.     If k = 1 Then imin = 2: imax = 8: jmin = 1234 Else imin = 12: imax = 98: jmin = 123
  6.     For i = imin To imax
  7.         For j = jmin To Int(9999 / i)
  8.             p = i * j
  9.             If IsPandigit(i & j & p) Then d(p) = ""
  10.         Next
  11.     Next
  12. Next
  13. Debug.Print Application.Sum(d.keys)
  14. End Sub

  15. Function IsPandigit(n) As Boolean   '判断n是否是Pandigit(由1-len(n)的所有数字组成)
  16.     If InStr(n, "0") > 0 Then Exit Function
  17.     For i = 1 To Len(n)
  18.         If InStr(n, i) = 0 Then Exit Function
  19.     Next
  20.     IsPandigit = True
  21. End Function

复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-19 01:04 , Processed in 7.326616 second(s), 6 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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