这道题目的经历让我感触很深,我做的题目是浙大的,链接在这里;
Humble Number 的原题可能是北大的,北大的题目更广义一些,是自定义的基数,浙大的只有(2,3,5,7)四个基。
题目看了一遍以后第一感觉就是2000000,n多个零的那个数,让我感觉遍历肯定是会傻的。所以一定是构造。
于是我写了下面第一个代码,思路是这样的,假设我们从某一段开始,已有了[1,2,3,4,5,6,7]这几个结果,
那么接下去的一个数,一定是前面的这些数乘以2,3,5,7得到的。
而对于1, 1×2=2, 1×3=3, 1×5=5, 1×7=7, 可见1的机会已经用完了。
那么对于2, 2×2=4, 2×3=6, 意味着还有5和7可以作为因子相乘。
于是我定义了一个结构:这个结构定义了with*,表示*已经被乘过了。
并且可以找出如下的结果,假设到12的时候,12以后这个数只会在2×7, 3×5, 4×3, 5×3, 6×2
中间产生。而我们发现这些数都是大于等于12, 所以要是等于12,就吧with* 标记成1。如果大于12,就找大于12最小数。
而找这些可能的结果也很简单,发现下图第二个矩阵中1排列是个左上三角,沿着边找就可以了。
这样看来这是一个极好的思路,我以为应该就能解决掉这个问题了。
于是有了下面的代码:
而事实上是结果出来了,但是非常的慢,后来我用time测试了一下,计算要求的5000个,话了6秒,晕,肯定过不了了。
后来的思路来自于这片文章,看了他的程序我豁然开朗。
并且找到了慢的原因,基数太多了!
人家用的大致思路是一样的,探索找下一个,然后填满5000个。
但是人家用了4个质数做了基,那么比较的次数就大大降低了,
而我用的是对角线数做基数,并且还有标记的工作,加上使用了类有开销,所以慢了100倍!!!我去……
我用python重写了一遍:
两种结果的比较,一个6秒一个0.06秒
我于是在想,习惯了用方便自己的思路做事,苦了我的电脑,哈哈!
算法的力量真大啊!