《编程之美》2.20 程序理解和时间分析

程序说明:

这个题目总共有三问:
1. 这个程序要找的是什么条件的数?
2. 这个数存在么?符合这一条件的最小的数是什么?
3. 在电脑商运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分钟(单核CPU2.0Hz)

-----------------------------------------------------------------------------------

 

首先解答1,见程序中//注释@1部分,是我添加的,就是解答这个问题。整个for循环中要求的数是:

 

从rg[0]到rg[j-1]都能整除i,从rg[j+2]到rg[29]都能整除i,唯独rg[j],rg[j+1]无法整除i,就是要找这样的i。

 

为了解这个问题,首先得找到rg[j]和rg[j+1],在它们的因子里须有其它rg[]元素分解不出的因子。

 

例如23,29这样的素数就行,但他们旁边的数大都能被其他数的因子“凑乘”出来,比如24=4x6=2x12..,30 = 3x10.. 等等

 

最终,我找到了唯一一组连续的数16,17。

 

由于rg中最大的数是31,所以作为2的幂,16可以满足不被其他数的因子凑出来(虽然能2x8,但2是8的因子,不算);

 

17是素数,显然满足条件。

 

这样就可以求解 i 了:i = 2 * 3 * 4 * 5 * ... * 15 * 18 * 19 * 20 *...* 30 * 31;

 

对了嘛?等等,别急。看这里有2,有4, 有8…… 乘起来早凑出来6了。所以,需要将“多余”的公因子约去再乘。

 

如下两行为约前与约后的比对:

 

i1 = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 18 * 19 * 20 *...* 30 * 31;

i2 = 2 * 3 * 2 * 5 * 1 * 7 * 2 * 3 * 1   * 11 * 1   * 13 * 1   * ....

 

比如,*6 变成 *1,是因为前面有了 2 * 3; *8 变成了 *2 ,因为前面有了2 * 2,以此类推。

 

最后得到了要求的i,最小的:2 1235 8166 0200,2万亿多。在注释2处将初始化i = 1改为这个数,验证正确:)

 

同时这也解答了第二题。第三题的话就按照这个数算clock cycle吧……

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值