2008年7月3日星期四

google寻宝 google treasure hunt prime 素数问题

偶然看见的题目,很有意思,一时技痒,试着解决一下:-)
题目翻译如下:
找一个最小的素数,使其满足一下条件:
分别可以表示成连续11,37,347,1157个素数之和。

如41是满足下面条件的最小素数:
同时满足连续3个,和6个的素数之和。
11 + 13 + 17 = 41,
2 + 3 + 5 + 7 + 11 + 13 = 41

题目中的数字是动态生成的。这是给我生成的题目。解法都一样。

Question:

Find the smallest number that can be expressed as
the sum of 11 consecutive prime numbers,
the sum of 37 consecutive prime numbers,
the sum of 347 consecutive prime numbers,
the sum of 1157 consecutive prime numbers,
and is itself a prime number.

For example, 41 is the smallest prime number that can be expressed as
the sum of 3 consecutive primes (11 + 13 + 17 = 41) and
the sum of 6 consecutive primes (2 + 3 + 5 + 7 + 11 + 13 = 41).



此题的答案是:9778121

程序:

        static bool isPrime(Int64 num)
{
if ((num == 2) || (num == 3))
return true;
Int64 sqrti = (Int64)Math.Sqrt(num) + 1;
for (Int64 i = 2; i < sqrti; i++)
{
if (num % i == 0)
return false;
}

return true;
}
static void Main(string[] args)
{
Int64 result = 0;
bool found = false;
Int64 endprime;
Int64 startprime = 2;
Int64 sumtotal = sum(startprime, 1157, out endprime);
Console.WriteLine(sumtotal);
Console.WriteLine(endprime);
while (!found)
{
while (!isPrime(sumtotal))
{
sumtotal = sumtotal + endprime - startprime;
startprime = findPrimeAfter(startprime);
endprime = findPrimeAfter(endprime);

}
Console.WriteLine("find temp prime sum:" + sumtotal);
if (splitprime(sumtotal, 11) && splitprime(sumtotal, 37) && splitprime(sumtotal, 347))
{
result = sumtotal;
found = true;
}
else
{
sumtotal = sumtotal + endprime - startprime;
startprime = findPrimeAfter(startprime);
endprime = findPrimeAfter(endprime);
}

}

Console.WriteLine("result:" + result);


}
static bool splitprime(Int64 prime, Int64 slicenum)
{
Int64 average = prime / slicenum;
Int64 lowprime = findPrimeBefore(average, slicenum);
// Int64 highprime = findPrimeAfter(average, slicenum);
Int64 startprime = lowprime;
Int64 endprime;
Int64 slicetotalnum = sum(startprime, slicenum, out endprime);
while ((startprime < average) && (slicetotalnum <= prime))
{
if (slicetotalnum == prime)
{
Int64 temp = startprime;
Console.Write(prime+"=");
while (slicenum-- > 0)
{
Console.Write(temp + "+");
temp = findPrimeAfter(temp);
}
Console.WriteLine();
return true;
}
slicetotalnum = slicetotalnum + endprime - startprime;
startprime = findPrimeAfter(startprime);
endprime = findPrimeAfter(endprime);

}
return false;
}
static Int64 sum(Int64 startprimenum, Int64 primenum, out Int64 endprimenum)
{
Int64 total = 0;
Int64 prime = startprimenum;
for (int i = 0; i < primenum; i++)
{
total += prime;
prime = findPrimeAfter(prime);
}
endprimenum = prime;
return total;
}
static Int64 findPrimeBefore(Int64 prime)
{
if (prime == 2)
return 2;
if (prime == 3)
return 2;
if (prime % 2 == 0)
prime = prime - 1;
else
{
prime = prime - 2;
}
while (!isPrime(prime) && prime > 0)
{
prime = prime - 2;
}
return prime;
}
static Int64 findPrimeBefore(Int64 prime, Int64 before)
{
while (before-- > 0 && prime > 0)
prime = findPrimeBefore(prime);
return prime;
}
static Int64 findPrimeAfter(Int64 prime, Int64 after)
{
while (after-- > 0)
prime = findPrimeAfter(prime);
return prime;
}
static Int64 findPrimeAfter(Int64 prime)
{
if (prime == 2)
return 3;
if ((prime & 1) == 1)
prime = prime + 2;
else
{
prime = prime + 1;
}
while (!isPrime(prime) && prime > 0)
{
prime = prime + 2;
}
return prime;
}

没有评论: