Antiprime解题报告

Antiprime解题报告


题目简述:

设n是一个自然数,如果所有小于n的自然数的约数个数都小于n的约数个数,则n是一个Antiprime数。譬如:1, 2, 4, 6, 12, 24。

给定一个自然数n(1 <= n <= 2 000 000 00),计算不大于n的最大Antiprime数。

基本思想:

定理 设p = 2^t1 * 3^t2 * …… * p^tk(其中p是第k大的质数)是Antiprime数,则必有:t1 >= t2 >= t3 >= … >= tk >= 0。
证明 若不然可将{ti}由大到小排序,设形成的新有序序列是{ti’},t1' >= t2' >= t3'  >= … >= tk';令p’ = 2^t1' * 3^t2' * …… * p^tk',则:p' < p,但p'的约数个数却不少于p(实际上两者约数个数相等),这与p是Antiprime数矛盾。所以必有:t1 >= t2 >= t3 >= … >= tk。

实现方法:

程序的核心是使用递归函数solve()获取所有符合上述定理得t序列。由multiply()求每一个序列对应的p值,再由count()求p值的因数的个数。在此过程中记录因数个数最多而本身数值最小的数即为antiprime数。

优化策略:

由于采用构造性的解法,题目的规模并不大,递归可以简洁而有效的解决问题。Profiling的结果也证明了这一点。低效的count()占用了100%的开销!改进的方法是使用已经求得t序列可以组合计算因数的个数,实现比较复杂。但我目前想不到比较简单的实现方式。目前的效率也可以接受,最大边界情况下我的600MHzCPU需要1.2s左右,所以就没有继续改进。


源代码:antiprime.tar.bz2   antiprime.c

附录:antiprime数搜索结果:
                1,
                2,
                4,
                6,
                12,
                24,
                36,
                48,
                60,
                120,
                180,
                240,
                360,
                720,
                840,
                1260,
                1680,
                2520,
                5040,
                7560,
                10080,
                15120,
                20160,
                25200,
                27720,
                45360,
                50400,
                55440,
                83160,
                110880,
                166320,
                221760,
                277200,
                332640,
                498960,
                554400,
                665280,
                720720,
                1081080,
                1441440,
                2162160,
                2882880,
                3603600,
                4324320,
                6486480,
                7207200,
                8648640,
                10810800,
                14414400,
                17297280,
                21621600,
                32432400,
                36756720,
                43243200,
                61261200,
                73513440,
                110270160,
                122522400,
                147026880,
                183783600,
                245044800,
                294053760,
                367567200,
                551350800,
                698377680,
                735134400,
                1102701600,
                1396755360

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值