【ProjectEuler】ProjectEuler_044

来源:互联网 发布:尚观linux视频 编辑:程序博客网 时间:2024/05/03 00:19
#pragma once#include <windows.h>class MoonMath{public:    MoonMath(void);    ~MoonMath(void);    //************************************    // Method:    IsInt    // Access:    public    // Describe:  判断double值在epsilon的范围内是否很接近整数    //            如1.00005在epsilon为0.00005以上就很接近整数    // Parameter: double doubleValue    要判断的double值    // Parameter: double epsilon        判断的精度,0 < epsilon < 0.5    // Parameter: INT32 & intValue      如果接近,返回最接近的整数值    // Returns:   bool                  接近返回true,否则返回false    //************************************    static bool IsInt(double doubleValue, double epsilon, INT32 &intValue);    //************************************    // Method:    Sign    // Access:    public    // Describe:  获取value的符号    // Parameter: T value   要获取符号的值    // Returns:   INT32     正数、0和负数分别返回1、0和-1    //************************************    template <typename T>    static INT32 Sign(T value);    //************************************    // Method:    IsPrimer    // Access:    public    // Describe:  判断一个数是否是素数    // Parameter: UINT32 num    要判断的数    // Returns:   bool          是素数返回true,否则返回false    //************************************    static bool IsPrimer(UINT32 num);    //************************************    // Method:    IsIntegerSquare    // Access:    public static    // Describe:  判断给定的数开平方后是否为整数    // Parameter: UINT32 num    // Returns:   bool    //************************************    static bool IsIntegerSquare(UINT32 num);};


 

#include "MoonMath.h"#include <cmath>MoonMath::MoonMath(void){}MoonMath::~MoonMath(void){}template <typename T>INT32 MoonMath::Sign(T value){    if(value > 0)    {        return 1;    }    else if(value == 0)    {        return 0;    }    else    {        return -1;    }}bool MoonMath::IsInt(double doubleValue, double epsilon, INT32 &intValue){    if(epsilon > 0.5 || epsilon < 0)    {        return false;    }    if(INT32(doubleValue + epsilon) == INT32(doubleValue - epsilon))    {        return false;    }    INT32 value = INT32(doubleValue);    intValue = (fabs(doubleValue - value) > 0.5) ? (value + MoonMath::Sign(doubleValue)) : (value) ;    return true;}bool MoonMath::IsPrimer(UINT32 num){    // 0和1不是素数    if(num <= 1)    {        return false;    }    UINT32 sqrtOfNum = (UINT32)sqrt((double)num); // num的2次方    // 从2到sqrt(num),如果任何数都不能被num整除,num是素数,否则不是    for(UINT32 i = 2; i <= sqrtOfNum; ++i)    {        if(num % i == 0)        {            return false;        }    }    return true;}bool MoonMath::IsIntegerSquare(UINT32 num){    UINT32 qurtNum = (UINT32)sqrt((double)num);    return (qurtNum * qurtNum) == num;}


 

//  Pentagon numbers// Problem 44// Pentagonal numbers are generated by the formula, Pn=n(3n1)/2. The first ten pentagonal numbers are:////  1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...//// It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70  22 = 48, is not pentagonal.//// Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference is pentagonal and D = |Pk  Pj| is minimised; what is the value of D?#include <iostream>#include <windows.h>#include <ctime>#include <assert.h>#include <string>#include <MoonMath.h>using namespace std;//************************************// Method:    CalcPentagonNum// Access:    public// Describe:  计算第n个Pentagon数// Parameter: UINT32 n// Returns:   UINT32//************************************inline UINT64 CalcPentagonNum(UINT32 n){    return UINT64(n) * (3 * n - 1) / 2;}//************************************// Method:    IsPentagonNum// Access:    public// Describe:  判断num是否是Pentagon数// Parameter: UINT32 num    要判断的Pentagon数// Parameter: UINT32 &n     如果是Pentagon数,返回n,否则返回无效值// Returns:   bool          是Pentagon数返回true,否则返回false//************************************bool IsPentagonNum(UINT64 num, UINT32 &n){    // 根据一元二次方程求解公式求出n的值    // 3*n^2-n-2*num=0    // n=(1+-sqrt(1+24*num))/6    // 因为n>0    // 所以n=(1+sqrt(1+24*num))/6    double nDouble = (1.0 + sqrt(1.0 + 24.0 * num)) / 6;    const double EPSILON = 0.00001; // 判断n是否为整数的精确度    n = 0;    // 如果n是整数,则视计算Pentagon的公式可逆推,num为Pentagon数    if(!MoonMath::IsInt(nDouble, EPSILON, (INT32 &)n))    {        return false;    }    return CalcPentagonNum(n) == num;}void TestFun1(){    UINT32 n = 0;    const UINT32 MAX_TEST_N = 100000000;    for(UINT32 i = 0; i < MAX_TEST_N; i++)    {        UINT64 pI = CalcPentagonNum(i);        if(!IsPentagonNum(pI, n))        {            cout << "i = " << i << endl << "CalcPentagonNum(i) = " << i << endl;        }    }    cout << "Test OK!";}void F1(){    cout << "void F1()" << endl;    // TestFun1();    LARGE_INTEGER timeStart, timeEnd, freq;    QueryPerformanceFrequency(&freq);    QueryPerformanceCounter(&timeStart);    /*********************************算法开始*******************************/    // d < j < k < x    // pD = p(d)    // pJ = p(J)    // p(k) - p(j) = p(d)    // p(k) + p(j) = p(x)    // p(d) >= p(j+1) - p(j)    否则p(j)+p(d)肯定不会是下一个Pentagon数    // 令m(n) = p(n+1) - p(n)    const UINT32 START_N = 1;    bool haveFound = false;    UINT32 j;    UINT32 d;    UINT32 k;    UINT32 x;    UINT64 pD = 0;    UINT64 pJ = 0;    UINT64 pK = 0;    for(k = START_N; !haveFound; k++)    {        for(j = k - 1; j >= START_N; j--)        {            pK = CalcPentagonNum(k);            pJ = CalcPentagonNum(j);            if(IsPentagonNum(pK - pJ, d) && IsPentagonNum(pK + pJ, x))            {                haveFound = true;                pD = pK - pJ;                break;            }        }    }    cout << "j = " << j << endl            << "pJ = " << pJ << endl            << "d = " << d << endl            << "pD = " << pD << endl            << "k = " << k << endl            << "pK = pD + pJ = " << pK << endl            << "x = " << x << endl            << "pX = pK + pJ = " << pK+pJ << endl;    /*********************************算法结束*******************************/    QueryPerformanceCounter(&timeEnd);    cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl;    time_t currentTime = time(NULL);    const char BEEP_CHAR = '\007';    const int MAX_TIME_CHAR = 30;    char timeStr[MAX_TIME_CHAR];    ctime_s(timeStr, MAX_TIME_CHAR, ¤tTime);    cout << endl << "By GodMoon" << endl << timeStr << BEEP_CHAR;    system("pause");}//主函数int main(){    F1();    return 0;}/*void F1()j = 1020pJ = 1560090d = 1912pD = 5482660k = 2168pK = pD + pJ = 7042750x = 2395pX = pK + pJ = 8602840Total Milliseconds is 432.123By GodMoonMon Mar 11 20:13:38 2013*/


 

原创粉丝点击