锁定老帖子 主题:一道算法题
精华帖 (2) :: 良好帖 (16) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-18
![]() |
|
返回顶楼 | |
发表时间:2010-09-18
![]() |
|
返回顶楼 | |
发表时间:2010-09-19
大于60位的自然数无水仙花数,最大的水仙花数是39位数,见《水仙花数的计算机解法》这一篇paper,此文统计了所有自然数中的88个水仙花数。
感兴趣的可以参看一下这篇论文里用到的算法。 楼主的方法和论文中的有相同之处,但是文章给出了证明过程。 |
|
返回顶楼 | |
发表时间:2010-09-19
你的代码很强悍...上次你的回答我不很明了,我并没回溯,只是加一个简单的判定条件if(offset==9),然后就可以用8代替9了,这是小事。
我有个基本问题没明白,还请指点! 最基本的就是你是如何遍历完从10的20次方到全9的二十一位数的遍历?... 通过分析,我觉得你是以countArray[0],countArray[1],一直到countArray[9]的和为恒定的Size为条件,逐次改变countArray[0]到countArray[9]的大小,来完成遍历的,但那样遍历的次数依旧很大啊...对于next()方法不好理解! |
|
返回顶楼 | |
发表时间:2010-09-20
SongChaoBin 写道 你的代码很强悍...上次你的回答我不很明了,我并没回溯,只是加一个简单的判定条件if(offset==9),然后就可以用8代替9了,这是小事。 我有个基本问题没明白,还请指点! 最基本的就是你是如何遍历完从10的20次方到全9的二十一位数的遍历?... 通过分析,我觉得你是以countArray[0],countArray[1],一直到countArray[9]的和为恒定的Size为条件,逐次改变countArray[0]到countArray[9]的大小,来完成遍历的,但那样遍历的次数依旧很大啊...对于next()方法不好理解! 我没有遍历每个数,只是遍历每个数的可能出现次数。 因为水仙花数就是每个数的出现次数的21次方之和。 这个数远远小于一个21位数,其大小就是将21个数插入10位的列中的可能次数, 即C(10,21)。 并且,在其中对大量可能性做了过滤处理,很多数还没计算就直接处理掉了。 所以要汇总计算的数据是很少的。 next()方法并不是要找到一个水仙花数,而是说下一个可能成立的数据。这个数不一定有21位,可能只有其中的部分信息,只要成立,就继续判断。 |
|
返回顶楼 | |
发表时间:2010-09-20
因为水仙花数就是每个数的出现次数的21次方之和。
这句话的原意应该是---水仙花数就是0^21*出现次数+1^21*出现次数+。。。。+9^21*出现次数 对吗?你的描述应该更清晰点,按你的描述有点看不懂。 |
|
返回顶楼 | |
发表时间:2011-04-29
这个一定要排序,否则时间复杂度很高。包含2道排序。
1. 把每个数的按照每一个位的大小,重新排序,例如 323456 排序后为 654332(必须保存排序之前的原始值。 2. 把整个集合的所有数进行从小到大或者从大到小的排序。 3. 过滤不符合要求的值,也就是N位数的每个位的N次方只和大于N位数的最大值或者小于其最小值的过滤掉,由于之前排序了,因此可以使用二分算法快速的过滤 不符合要求的数。 4.对剩下的数遍历,每个计算并验证。对每个数的计算时,如果前面的M(M < N)位的N次方之和 已经大于本数,则立刻放弃。类似于 布尔运算的短路规则 一样。不同的数,通过第1步排序后的值可能相同。把排序后的数值称为 V,排序之前的值称为R。每个V都有一个R队列,对R队列进行从大到小的排序。计算时,如果前面M位的N次方只和大于R队列的最大值,则可全部跳过。否则知道计算完N个。如果其值小于R队列的最小值,也可以跳过。如果结果值在R队列的最大和最小范围之间,则一一比较是否有相等的。此时只能有一个是与该值相等的,找到一个即可。 |
|
返回顶楼 | |
发表时间:2011-05-01
不怎么看得懂
|
|
返回顶楼 | |
发表时间:2011-05-01
看了newZai的描述,有点意思了
|
|
返回顶楼 | |