浏览 88 次
|
该帖已经被评为新手帖
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-07-25 关键字: project euler problem 108
题目如下(problem 108):
In the following equation x, y, and n are positive integers. 1/x + 1/y = 1/n For n = 4 there are exactly three distinct solutions: 1/5 + 1/20 = 1/6 + 1/12 = 1/8 + 1/8 =1/4 1. What is the least value of n for which the number of distinct solutions exceeds 1000? 2. What is the least value of n for which the number of distinct solutions exceeds 4,000,000? 我原来的思路: 设0<x<=y,由等式可求出x的范围为 n < x <= 2n y = nx / (x - n) 循环遍历x,如果nx % (x-n) == 0 则说明有一个解成立 但这样的解法,太耗时间了,第1问就已经花了我较长时间,第1问的答案为180180 我觉得似乎和n的因子有关,但研究了两个晚上没有头绪 主要代码如下:
/**
* 1/x + 1/y = 1/n
*
* x <= y
*
* n <= x <= 2n
*
* y = (x*n)/(x-n)
*/
public static int solution(long n) {
int count = 0;
for (long x = n + 1; x <= 2 * n; x++) {
if ((x * n) % (x - n) == 0) {
count++;
}
}
return count;
}
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2008-07-25
忘了说了,第二问是problem 110
|
|
| 返回顶楼 | |
|
时间:2008-07-26
下面是Scala代码,一分钟内可以算出来:
会Java就应该能看懂:
object Euler110 extends Application {
def find(bound:Int):BigInt = {
import scala.Math._
val ps = Array(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53)
val lp = ps.subArray(0,ceil(log(2*bound-1)/log(3)).toInt-3).map{ n => n:BigInt}
var min = ps.subArray(0,ceil(log(2*bound-1)/log(3)).toInt).foldLeft(1:BigInt){ _*_ }
def find0(v:BigInt,mul:Int,upper:Int,idx:Int){
if(v >= min) return
if(mul > 2*bound-1){
min = v
return
}
if(idx >= lp.length) return
for(n <- 0 to upper) find0(v*lp(idx).pow(n),mul*(2*n+1),upper,idx+1)
}
find0(1,1,4,0)
min
}
println(find(4000000))
}
答案是:9350130049860600 算法的原理是: 引用 30 Dec 2005 11:04 pm euler (PHP) euler is from England Quote You're right about the number of unit fraction sums, but it would need to be the number of divisors of n2 which are less than or equal to n, otherwise we would include symmetrically equivalent solutions. Xaphiosis, you're right about not finding Diophantine equations with negative indices, so in problems like this the trick is to eliminate the denominators... From 1/x + 1/y = 1/n we get nx + ny = xy. ny = xy - nx = x(y - n) x = ny/(y - n) Let k = y - n (y = k + n). So x = n(k + n)/k = n + n2/k. If x is integer then k must divide n2. However... Without loss of generality, let us assume that y ≤ x. Therefore y = k + n ≤ x = n + n2/k. k ≤ n2/k k2 ≤ n2 Hence k ≤ n. For example, if n = 6, n2 = 36, so k = {1,2,3,4,6,9,12,18,36}. But we only want k ≤ n; that is, k = {1,2,3,4,5,6}. We can use this set of k to find x and y... Recall that y = n + k, and x = ny/(y - n) = ny/k. So we get (7,42), (8,24), (9,18), (10,15), (12,12). If we included k = {9,12,18,36} it would give (15,10), (18,9), (24,8), and (42,7). Based on this symmetry it should be clear why the closed formula (which I had completely missed until RogerHui kindly provided the link) is: (d(n2)+1)/2, where d(n) is number of divisors function. Because you will recall that n2 has an odd number of divisors, so we add one before dividing by 2 (subtracting one would lose the "middle" divisor). 31 Dec 2005 01:26 am neverforget (PARI/GP) neverforget is from USA Quote From Sloane's A018892: If n = (p1^a1)(p2^a2)...(pt^at), 2-partitions = ((2 a1 + 1)(2 a2 + 1) ... (2 at + 1) + 1)/2. We want ((2 a1 + 1)(2 a2 + 1) ... (2 at + 1) + 1)/2 > 1000 (2 a1 + 1)(2 a2 + 1) ... (2 at + 1) >= 2000 |
|
| 返回顶楼 | |
|
时间:2008-07-26
这里题目可以抽象为下列问题:
已知整数 a1,a2,..,an满足 (2*a1+1)*(2*a2+1)...*(2*an+1) > K (K为给定常数) 以及给定自然数 p1,p2,...,pn 求 min{ p1^a1*p2^a2*..*pn^an} 我上面使用的是搜索来寻找这个值。 其还有一种思路: 对:p1^a1*p2^a2*..*pn^an 取自然对数得: a1*ln(p1)+a2*ln(p2)+..+an*ln(pn) 其中ln(x)表示自然对数 ln(x)是单增函数,因此只需要求上式的最小值,亦只需求: (2*a1+1)*ln(p1)+(2*a2+1)*ln(p2)+..+(2*an+1)*ln(pn) 的最小值 由均值不等式知: (2*a1+1)*ln(p1)+(2*a2+1)*ln(p2)+..+(2*an+1)*ln(pn) >= 6{(2*a1+1)*ln(p1)*(2*a2+1)*ln(p2)*..*(2*an+1)*ln(pn)}^(1/6) =6*C (C是和K以及p1,p2,..有关的一个常数) 而且等号成立的条件是 a1 = {C/ln(p1)-1}/2 ... 这样可以求出a1,a2,...但注意,这里得到的a1,a2是double类型的,所以还需要对其进行微调离散化。 这个方法只需要用纸和笔就能搞定 |
|
| 返回顶楼 | |




