Project Euler Problem 27小結

Project Euler上有很多有意思的問題,剛做到第27題,對這個問題做個小結。

 

Problem 27:

Euler有一個著名的方程n^2+n+41,當n=0到39時,方程結果均爲質數。如今人們用電腦計算,發現了另一個方程n^2-79n+1601,當n=0到79時,方程結果也均爲質數。

設一方程形如n^2+an+b,其中|a|<1000,|b|<1000,n爲從0開始的連續自然數。

求使得公式能獲得最多質數的a和b,輸出結果爲a*b。

 

問題很簡單,首先寫好判斷質數的方法:

bool isPrime(int Num)
{
    for(unsigned long int n=2; n<=sqrt(Num);n++)
    {
        if(Num%n == 0)
        {
            return false;
        }
    }
 
    return true;
}

然後直接窮舉遍歷,搜索符合條件的a和b,寫出程序第一版:

void Euler_Cal_27()
{
    int n=0;
    int maxn = 0;
    int expr = 0;
    int result = 0;
   
    for(int a=-999; a<1000; a++)
    {
        for(int b=-999; b<1000; b++)
        {
            n = 0;
            expr = n*n + a*n + b;
 
            while(isPrime(expr) &&expr>0)
            {
                n++;
                expr = n*n + a*n + b;
            }
 
                if( n>maxn )
                {
                    maxn = n;
                    result = a*b;
                }
            }
        }
    }
 
    cout<< result <<endl;
}

電腦CPU是E6600,得到正確結果用時1.4s。雖然用時不長,但是搜索範圍很小,所以肯定有提高的餘地。優化自然先從循環着手,仔細檢查一下發現while循環條件順序有誤。&&運算只要前一個條件爲假就不進行後面條件的判斷,而這裏恰恰將判斷質數放在判斷正負這種簡單運算前面,影響速度。所以調換條件順序,此時程序運行時間減少至0.3s。又看了一會兒之後再沒想到其他優化方法,所以上論壇看看其他人是如何解決的。一看果然有收穫。

1、 n須從0開始,所以當n=0時,方程結果必爲質數,否則此時的a和b肯定不是最優結果。而n=0時,方程結果是b,所以b必須爲質數。

2、 當n=1時,方程結果爲1+a+b,質數必須大於0,所以有a>-b-1。即確定b後,可以縮小a的搜索範圍。

還有人事先生成質數表,通過查表來判斷質數,減少運行時間。但是這種方法在改變搜索範圍時需要重新生成質數表,有些麻煩,所以沒有使用。僅依照以上提到的兩個條件進行優化,第二版代碼如下:

voidEuler_Cal_27()
{
    int n=0;
    int maxn = 0;
    int expr = 0;
    int result = 0;
 
    for(int b=1; b<1000; b++)
    {
        if(isPrime(b))
        {
            for(int a=-b; a<1000; a++)
            {
                n = 0;
                expr = n*n + a*n + b;
 
                while( expr>0 && isPrime(expr) )
                {
                    n++;
                    expr = n*n + a*n + b;
                }
 
                if( n>maxn )
                {
                    maxn = n;
                    result = a*b;
                }
            }
        }
    }
 
    cout<< result <<endl;
}

此時程序運行時間減少至0.17s。

從這次優化小程序發現,優化程序時大多從代碼本身入手,忽略問題,不去想原理,在進一步提高程序性能的時候容易遇到瓶頸。以後要注重鍛鍊自己理解問題的能力,基礎還是很差,需要提高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章