Project Euler 27

来源:互联网 发布:怎么使用oracle数据库 编辑:程序博客网 时间:2024/06/05 07:23

木哈哈~咩哈哈~


终于写出了一个经过深思熟虑才写出的代码~好久没有这种感觉了!!


题目大意就是欧拉大神找到这样一个公式,n^2+n+41, 这个公式的神奇之处在于,n in range(0, 40) 满足return的value全都是prime

这个非常神奇,真心不知道他怎么算的……


题目还给出了另外一个公式,n^2-79n+1601, 这也是神奇公式,n in range(0 80) ,同上述。


题目要求我们算出,n^2+an+b 保证尽量多的n,从n=0开始,连续的。(艹……中文不会讲了……英语也不会讲……)

Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0.

同时,where |a< 1000 and |b< 1000


嗯,我是这样分析的


首先,n从0开始,那么第一项就是 0+0+b,那么b肯定要是一个质数。而且是一个正的质数,b<0情况不用考虑啦~

第二,n=1,1+a+b肯定要保证是个质数,那才有算下去的必要。所以,a> -b-1(这里写成1-b也行,为什么呢?哈~)

第三,因为欧拉给出了一个式子,我们要算的肯定比他多,那么一个优化就是,40^2+40a+b>0  =>  a > -b/40 -40

在这两个限制条件中,选一个大的,算作min_a,然后暴力枚举n。(n最大不会超过80的!)


当然,首先要把prime numnber都算出来,O(nlogn)


这样总共时间复杂度应该大约是O(1000*log1000+m*1000*80)神马神马的……随便写写,m表示小于1000的prime number个数。

肯定会挺快的啦~


下面上代码,有些可以优化的细节,就直接忽略了……

#include <stdio.h>#define SIZE 30000int prime[SIZE];int prime_list[10000];int n_prime;intfindPrime()/*比较经典的数素数,筛法选素数*/{int i, j;int *p;p = prime_list;for (i=0; i<SIZE; i++)prime[i] = 1;prime[0] = 0; prime[1] = 0;i = 2; *p = 2; j = i*i;while (j<SIZE){prime[j] = 0;j += i;}for (i=3; i<SIZE; i +=2)if (prime[i]){*(++p) = i;j = i*i;while (j<SIZE){prime[j] = 0;j += i;}}n_prime = p - prime_list;return 0;}intcalcFormula(int a, int b){int n, tmp;for (n=0; n<100; n++){tmp = n*n + a*n + b;if (!prime[tmp]){return n;}}return 0;}intmain(){int max = 0;int a, b, i;int now, min_a, num, xa, xb;findPrime();max = 0;for (i=12; i<n_prime; i++){b = prime_list[i];if (b >= 1000)break;min_a = -b/40 - 40;min_a = min_a < (1-b) ? (1-b) : min_a;num = 0;for (a=min_a; a<1000; a++){now = calcFormula(a, b);if (now > max){max = now;xa = a;xb = b;}}}printf("%d, %d, %d", max, xa, xb);return 0;}

用时

$ time ./a
71, -61, 971
real    0m0.063s
user    0m0.000s
sys     0m0.000s

原创粉丝点击