#pragma once#include <windows.h>#include <vector>#include <set>using namespace std;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); const static UINT32 MIN_PRIMER = 2; // 最小的素數 //************************************ // 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); //************************************ // Method: GetDiffPrimerFactorNum // Access: public static // Describe: 擷取num所有的不同質因數 // Parameter: UINT32 num // Returns: set<UINT32> //************************************ static set<UINT32> MoonMath::GetDiffPrimerFactorNum(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){ if(num < MIN_PRIMER) { return false; } UINT32 sqrtOfNum = (UINT32)sqrt((double)num); // num的2次方 // 從MIN_PRIMER到sqrt(num),如果任何數都不能被num整除,num是素數,否則不是 for(UINT32 i = MIN_PRIMER; 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;}set<UINT32> MoonMath::GetDiffPrimerFactorNum(UINT32 num){ UINT32 halfNum = num / 2; set<UINT32> factors; for(UINT32 i = 2; i <= halfNum; ++i) { if(!MoonMath::IsPrimer(i)) { continue; } if(num % i == 0) { factors.insert(i); while(num % i == 0) { num /= i; } } } return factors;}
// Consecutive prime sum// Problem 50// The prime 41, can be written as the sum of six consecutive primes://// 41 = 2 + 3 + 5 + 7 + 11 + 13// This is the longest sum of consecutive primes that adds to a prime below one-hundred.//// The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.//// Which prime, below one-million, can be written as the sum of the most consecutive primes?#include <iostream>#include <windows.h>#include <ctime>#include <assert.h>#include <vector>#include <MoonMath.h>using namespace std;// 列印時間等相關資訊class DetailPrinter{public: void Start(); void End(); DetailPrinter();private: LARGE_INTEGER timeStart; LARGE_INTEGER timeEnd; LARGE_INTEGER freq;};DetailPrinter::DetailPrinter(){ QueryPerformanceFrequency(&freq);}//************************************// Method: Start// Access: public// Describe: 執行每個方法前調用// Returns: void//************************************void DetailPrinter::Start(){ QueryPerformanceCounter(&timeStart);}//************************************// Method: End// Access: public// Describe: 執行每個方法後調用// Returns: void//************************************void DetailPrinter::End(){ QueryPerformanceCounter(&timeEnd); cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl; const char BEEP_CHAR = '\007'; cout << endl << "By GodMoon" << endl << __TIMESTAMP__ << BEEP_CHAR << endl; system("pause");}/*************************解題開始*********************************///************************************// Method: MakePrimerVector// Access: public// Describe: 擷取[0,maxNum]的所有素數,存入primers// Parameter: UINT32 maxNum 要找的最大值// Parameter: vector<UINT32> & primers 輸出素數數組,素數由小到大排列// Returns: void//************************************void MakePrimerVector(UINT32 maxNum, vector<UINT32> &primers){ for(UINT32 num = MoonMath::MIN_PRIMER; num <= maxNum; ++num) { if(MoonMath::IsPrimer(num)) { primers.push_back(num); } }}//************************************// Method: GetSum// Access: public// Describe: 計算迭代器[itBegin,itEnd)的和// Parameter: const vector<UINT32>::const_iterator & itBegin// Parameter: const vector<UINT32>::const_iterator & itEnd// Returns: UINT32//************************************UINT64 GetSum(const vector<UINT32>::const_iterator &itBegin, const vector<UINT32>::const_iterator &itEnd){ UINT64 sum = 0; for(vector<UINT32>::const_iterator it = itBegin; it != itEnd; ++it) { sum += *it; } return sum;}void TestFun1(){ cout << "Test OK!" << endl;}void F1(){ cout << "void F1()" << endl; // TestFun1(); DetailPrinter detailPrinter; detailPrinter.Start(); /*********************************演算法開始*******************************/ const UINT32 MAX_NUM = 1000000; vector<UINT32> primers; MakePrimerVector(MAX_NUM - 1, primers); UINT32 count = primers.size(); UINT64 currSum = 0; bool notFound = true; vector<UINT32>::const_iterator itBegin; // 數列的第一個數 vector<UINT32>::const_iterator itEnd; // 數列的最後一個數的下一個元素! itBegin = primers.begin(); // numCount為數列中的數字個數 for(UINT32 numCount = count; numCount > 0 && notFound; --numCount) { itEnd = itBegin + numCount; // 擷取第一組數列,索引範圍[0,numCount-1] currSum = GetSum(itBegin, itEnd); if(currSum < MAX_NUM && MoonMath::IsPrimer(currSum)) { break; } UINT32 remainSetCount = count - numCount; // 剩餘的數列個數 for(UINT32 setIndex = 0; setIndex < remainSetCount; ++setIndex) { // 計算下一組數列和,減去前一個數,加上後一個數 currSum = currSum - primers[setIndex] + primers[setIndex + numCount]; if(currSum < MAX_NUM && MoonMath::IsPrimer(currSum)) { itBegin += setIndex + 1; itEnd += setIndex + 1; notFound = false; break; } } } cout << currSum << " is sum of " << *itBegin << " to " << *(itEnd - 1) << endl; cout<<"sum is "<<GetSum(itBegin,itEnd)<<endl; /*********************************演算法結束*******************************/ detailPrinter.End();}//主函數int main(){ F1(); return 0;}/*void F1()997651 is sum of 7 to 3931sum is 997651Total Milliseconds is 1.60107e+006*/