1. 程式人生 > >Project Euler Problem 44

Project Euler Problem 44

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

and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised; what is the value of D?

#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; }