找回密码
 注册
Simdroid-非首页
查看: 227|回复: 3

[编程进阶] 征求“水仙花数”高效算法

[复制链接]
发表于 2010-3-23 00:54:47 | 显示全部楼层 |阅读模式 来自 河南郑州
本帖最后由 chyanog 于 2010-3-26 13:07 编辑

可能大家都知道,绝大多数编程基础书中都有水仙花数这一经典问题 。广义的水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3 + 3^3 = 153),它的求法可真不少。我用M@写了几种,先以三位的为例,如下:
(1)

  1. For[a = 1, a <= 9, a++,
  2. For[b = 0, b <= 9, b++,
  3.   For[c = 0, c <= 9, c++,
  4.    If[FromDigits[{a, b, c}] == Total[{a, b, c}^3], Print[a, b, c]]]]]
复制代码
(2)

  1. For[n = 100, n < 1000, n++,
  2.   a = Mod[n, 10];(*IntegerDigits[n][[1]]*)
  3.   b = Mod[IntegerPart[n/10], 10]; (*Mod[Quotient[i,10], 10] 或IntegerDigits[n][[2]]*)
  4.   c = IntegerPart[n/100];(*Quotient[i,100]或IntegerDigits[n][[3]]*)
  5.   If[a^3 + b^3 + c^3 == n,
  6.    Print[n]]] // Timing
复制代码
(3)

  1. Select[Tuples[Range[0, 9], 3],
  2.   Tr[{#[[1]], #[[2]], #[[3]]}^3] ==
  3.     FromDigits[{#[[1]], #[[2]], #[[3]]}] &] // Timing
复制代码
(4)

  1. Reduce[a^3 + b^3 + c^3 == FromDigits[{a, b, c}] && 1 <= a <= 9 &&
  2.    0 <= b <= 9 && 0 <= c <= 9, {a, b, c}, Integers] // Timing
复制代码
以下两个为不限位数的算法:
(5)

  1. Module[{n, i, k, s, t1, t2},
  2.   n = Input["输入不小于3的自然数n:"];
  3.   i = 10^(n - 1);
  4.   While[i <= 10^n - 1,
  5.    s = 0;
  6.    k = 1;
  7.    While[k <= n,
  8.     t1 = IntegerPart[i/10^(k - 1)]; (*Floor[i/10^(k-1)];*)
  9.     t2 = Mod[t1, 10]^n;
  10.     s = s + t2;
  11.     k++];
  12.    If[s == i, Print];
  13. i++];
  14.   ] // Timing
复制代码
(6)

  1.   Module[{n},
  2.   n = Input["请输入不小于3的自然数:"];
  3.   Select[Range[10^(n - 1), 10^n - 1],
  4.    Tr[IntegerDigits[#]^n] == # &]] // Timing
复制代码
其中最后一个是我写的效率相对较高也最简洁的啦,(之所以用Tr是因为多次测试发现它往往比Total更快,有点儿郁闷)
不过,当所求的水仙花数位数为7时,运行时间就几乎60s了,位数更高时就难以想象了。不知道我的代码是否可以再优化一下,或者还有其他精妙的算法,恳请诸位方家赐教!
发表于 2010-3-23 10:06:48 | 显示全部楼层 来自 北京
Simdroid开发平台
并不是每个人都知道所谓的水仙花数的概念的,
尤其是你所谓的位数不等于3时的水仙花数的概念.
为什么你的第6种情况下要求输入的数字不小于3呢?
回复 不支持

使用道具 举报

 楼主| 发表于 2010-3-23 20:41:47 | 显示全部楼层 来自 河南郑州
3# waynebuaa
不知这位朋友用的是哪种语言,算法上可否告知呢?
回复 不支持

使用道具 举报

发表于 2010-3-23 20:51:13 | 显示全部楼层 来自 北京丰台
  1. n = Input["Input  >2  integer n:"];
  2. For[i = 10^(n - 1), i < 10^n - 1, i++,
  3. If[Total[IntegerDigits[i]^IntegerLength[i]] == i, Print[i]]]
复制代码
回复 不支持

使用道具 举报

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

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2026-1-7 03:51 , Processed in 0.029802 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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