Project Euler Problem 44
阿新 • • 發佈:2018-11-02
Problem 44 : Pentagon numbers
Pentagonal numbers are generated by the formula, Pn=n(3n−1)/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
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
using namespace std;
// #define UNIT_TEST
class PE0044
{
private:
bool checkSquare(double num);
int calcPentagonalNumber(int n);
bool checkPentagonalNumber(int num, int& n);
bool findD(int n, int max_n, int& m, int& D);
public:
bool getValueOfD(int& m, int& D);
};
bool PE0044::checkSquare(double num)
{
int n = (int)sqrt(num);
if ((double )(n*n) == num)
{
return true;
}
return false;
}
int PE0044::calcPentagonalNumber(int n) // calculate P(n)
{
double Pn = (double)(n*(3*n-1) / 2.0);
return (int)Pn;
}
bool PE0044::checkPentagonalNumber(int num, int& n)
{
// num = n(3n-1)/2 => n = (1+sqrt(1+24*num))/6
long double temp = (long double)(1+24*num);
if (true == checkSquare(temp))
{
int n1 = (int)(1+sqrt(temp));
if (0 == n1%6 && n1/6 > 0)
{
n = n1/6;
return true;
}
}
return false;
}
bool PE0044::findD(int n, int max_n, int& m, int& D)
{
vector<int> Pn_v;
int Pn;
for (int i=n; i<max_n; i++)
{
Pn = calcPentagonalNumber(i);
Pn_v.push_back(Pn);
}
int n1 = 0; // Pn_v[k]+Pn_v[j] = P(n1)
int m1 = 0; // Pn_v[k]-Pn_v[j] = P(m1)
D = m = 0; // set initial value
for(unsigned int j=0; j<Pn_v.size()-1; j++)
{
for(unsigned int k=j+1;k<Pn_v.size(); k++)
{
if ((true == checkPentagonalNumber(Pn_v[k]+Pn_v[j], n1)) &&
(true == checkPentagonalNumber(Pn_v[k]-Pn_v[j], m1)))
{
#ifdef UNIT_TEST
cout << "P(" << n1 << ") = " << Pn_v[k]+Pn_v[j] << endl;
cout << "P(" << m1 << ") = " << Pn_v[k]-Pn_v[j] << endl;
#endif
D = Pn_v[k] - Pn_v[j];
m = m1;
return true;
}
}
}
return false;
}
bool PE0044::getValueOfD(int& m, int& D)
{
int n=1, max_n = 3000;
bool found = false;
while(false == found)
{
found = findD(n, max_n, m, D);
max_n += 2000;
}
return found;
}
int main()
{
#ifdef UNIT_TEST
clock_t start = clock();
#endif
PE0044 pe0044;
int m = 0 , D = 0;
pe0044.getValueOfD(m, D); // D = P(m)
cout << "D = P(" << m << ") = " << D << endl;
#ifdef UNIT_TEST
clock_t finish = clock();
double duration = (double)(finish - start) / CLOCKS_PER_SEC;
cout << "C/C++ application running time: " << duration << " seconds" << endl;
#endif
return 0;
}