也看有道第2题,无代码无真相

最近好多人都参与了有道的比赛,其中第2题园子里有很多人给出了程序,在这里我也小谈一下我的想法。

题目要求:双倍超立方数是指一个正整数可以正好被拆分为两种不同的a^3+b^3的方式,其中a,b均为整数且0<a<=b。对于任何一个指定的 int n, 返回所有的小于等于n的双倍超立方数的个数。

Returns: 0

1)  
      1729

Returns: 1
1729=1^3+12^3
1729=9^3+10^3

2)  
      475574

Returns: 27

看了好多人的博客,都是源程序,猛地一看,还看得不怎么明白,自己也copy了一些成功人士的代码,试着做做改进,但在优化的过程中,猛地发现:我这是在搞算法吗?还是在搞程序?

什么是算法?看维基:http://zh.wikipedia.org/w/index.php?title=%E7%AE%97%E6%B3%95&variant=zh-cn

 算法是指完成一个任务所需要的具体步骤和方法。也就是说给定初始状态或输入数据,能够得出所要求或期望的终止状态或输出数据。

算法常常含有重复的步骤和一些比较或逻辑判断。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度时间复杂度来衡量。

也就是算法是解决问题的办法,利用想出来的办法来解决现有的难题。

我们回头看一下题目,双超立方数,我没有搜到相关的定义,倒是维基里有17294104两个数的说明。这两个数都可以恰巧写成两个数立方和的形式,而且只有两种。

1729=1^3+12^3=9^3+10^3(这类数列的第一个)

4104=9^3+15^3=2^3+16^3

原题的意思即使找出小于n的能表示为上述形式的数字的数目。

看到题目好多人可能首先想起的是立方和公式:

a^3+3*a^2*b+3*a*b^2+b^3=(a+b)^3

对,化简之后就可以表达为:

a^3+b^3=(a+b)*(a^2-a*b+b^2)

首先我们应该能观察出双超立方数N应该不是素数,而且根据题目,应该恰好只有两对约数满足上面的式子,

即 

a+b=A                      

a^2-a*b+b^2=B   

这是一个二元二次方程组,应该只有两组解。

我的思路是遍历小于n的自然数,然后找出只有四个约数的数字(除了1和自身),然后将这两组组解分别带入求得a和b。

将1式变成b=A-a带入到2式,得:

3*a^2-3*A*a+A^2-B=0

这是一个一元二次方程,有解的话,还记得吗?初中学 的,Δ >=0,今天解这个我费了老劲了,简单的带入变换老做错。

但是在这里我们知道,对于每一组给定的A和B,上面的方程应该有两个不同的整数解,

那就得Δ >0,下买你求Δ

Δ =(3*A)^2-4*3*(A^2-B)=4*B-A^2,要知道结果是整数解,所以4*B-A^2必能开平方。

所以两个解a,b是这是维基的图,只是借用其形式。

最后问题就变成了一个求不定方程组的问题,而且解都是自然数。

其中能归纳出一些数学约束关系出来,利用计算机程序确定范围求解。

我没有最后实现这个方法,只是想到了个也许能解决问题的方法,希望能给大家以帮助。

 搞算法先将问题数学化,解决后再转化为程序。

 后记:

相信很多人都听说过《计算机程序设计艺术》比尔·盖茨在1995年说,“如果你认为你是一名真正优秀的程序员,就去读第一卷,确定可以解决其中所有的问题。”“如果你能读懂整套书的话,请给我发一份你的简历。”我至今没有敢动这部书,实在是不敢读。这糟老头子堪比霍金。

Donald Ervin Knuth

posted @ 2009-06-03 22:22  DiggingDeeply  阅读(1609)  评论(7编辑  收藏  举报