#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); //************************************ // 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){ // 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;}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;}
// Prime permutations// Problem 49// The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.//// There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.//// What 12-digit number do you form by concatenating the three terms in this sequence?#include <iostream>#include <windows.h>#include <ctime>#include <assert.h>#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: GetDigitMap// Access: public// Describe: 擷取num包含的數字map// Parameter: UINT32 num// Parameter: UINT16 & digitMap 返回的num的數字map// Returns: bool 如果包含重複的數字,返回false,否則返回true//************************************bool GetDigitMap(UINT32 num, UINT16 &digitMap){ UINT32 digit = 0; digitMap = 0; while(num != 0) { digit = num % 10; num /= 10; // 數字已存在,返回false if(digitMap & (1 << digit) == 1) { return false; } digitMap |= (1 << digit); } return true;}//************************************// Method: IsSameDigitNum// Access: public// Describe: 判斷N個數字是否都是由相同的數字組成,每個數字都必須包含不同的數字// Parameter: UINT32 num1// Parameter: UINT32 num2// Returns: bool//************************************bool IsSameDigitNum(const UINT32 nums[], UINT32 numCount){ UINT16 lastDigitMap = 0; UINT16 currDigitMap = 0; if(numCount <= 2) { return false; } if(!GetDigitMap(nums[0], lastDigitMap)) { return false; } for(UINT32 i = 1; i < numCount; ++i) { if(!GetDigitMap(nums[i], currDigitMap)) { return false; } if(currDigitMap != lastDigitMap) { return false; } } return true;}void TestFun1(){ cout << "Test OK!" << endl;}void F1(){ cout << "void F1()" << endl; // TestFun1(); DetailPrinter detailPrinter; detailPrinter.Start(); /*********************************演算法開始*******************************/ const UINT32 START_NUM = 1000; const UINT32 END_NUM = 9999; const UINT32 SKIP_NUM=1487; // 排除已有的數字 UINT32 maxAddNum = 0; UINT32 nums[3]; bool notFound = true; UINT32 addNum; UINT32 num; for(num = START_NUM; num <= END_NUM && notFound; ++num) { maxAddNum = (END_NUM - num) / 2; nums[0] = num; if(!MoonMath::IsPrimer(num)) { continue; } if (num==SKIP_NUM) { continue; } for(addNum = 1; addNum <= maxAddNum; ++addNum) { nums[1] = num + addNum; nums[2] = num + addNum * 2; if(IsSameDigitNum(nums, ARRAYSIZE(nums)) && MoonMath::IsPrimer(nums[1]) && MoonMath::IsPrimer(nums[2])) { notFound = false; break; } } } cout << "The 12-digit number is " << nums[0] << nums[1] << nums[2] << endl; /*********************************演算法結束*******************************/ detailPrinter.End();}//主函數int main(){ F1(); return 0;}/*void F1()The 12-digit number is 296962999629Total Milliseconds is 202.389By GodMoonWed Mar 13 20:54:30 2013*/