#pragma once#include <string>#include <Windows.h>using namespace std;class MoonBigNum{public: MoonBigNum(void); MoonBigNum(const string &num); MoonBigNum(const UINT32 &num); MoonBigNum(const MoonBigNum &bigNum); ~MoonBigNum(void); //************************************ // Method: Value // Access: public // Describe: 擷取大數的值 // Returns: const string & //************************************ const string &Value()const; //************************************ // Method: operator+ // Access: public // Describe: 大數相加 // Parameter: const BigNum & right // Returns: const BigNum //************************************ const MoonBigNum operator+(const MoonBigNum &right)const; //************************************ // Method: operator== // Access: public // Describe: 判斷2個大數是否相等 // Parameter: const BigNum & right // Returns: bool //************************************ bool operator==(const MoonBigNum &right)const; //************************************ // Method: operator< // Access: public // Describe: 實現小於比較 // Parameter: const BigNum & right // Returns: bool //************************************ bool operator<(const MoonBigNum &right)const; //************************************ // Method: operator> // Access: public // Describe: 實現大於比較 // Parameter: const BigNum & right // Returns: bool //************************************ bool operator>(const MoonBigNum &right)const; //************************************ // Method: operator++ // Access: public // Describe: 前自增,++value // Returns: BigNum //************************************ MoonBigNum operator++(); //************************************ // Method: operator++ // Access: public // Describe: 後自增,value++ // Parameter: int // Returns: BigNum //************************************ MoonBigNum operator++(int); //************************************ // Method: operator+= // Access: public // Describe: 重載+= // Parameter: MoonBigNum & right // Returns: MoonBigNum //************************************ MoonBigNum operator+=(MoonBigNum &right); MoonBigNum operator+=(UINT32 num); //************************************ // Method: Reverse // Access: public // Describe: 數字逆轉,比如123變成321,但是2000會變成2 // Returns: BigNum //************************************ MoonBigNum Reverse()const;private: string numStr;};
#include "MoonBigNum.h"#include "MoonString.h"MoonBigNum::MoonBigNum(void): numStr(""){}MoonBigNum::MoonBigNum(const string &num){ string::size_type length = num.size(); UINT32 startIndex = 0; // 起始轉換位置,主要是為了排除前面的0 for(string::size_type i = 0; i < length; ++i) { if(startIndex == i && num[i] == '0') { ++startIndex; } if(!isdigit(num[i])) { numStr = ""; return; } } // 輸入串全是0:"0000" if(startIndex == length) { --startIndex; } // 提高效率 if(startIndex == 0) { numStr = num; } else { numStr = num.substr(startIndex); }}MoonBigNum::MoonBigNum(const UINT32 &num): numStr(MoonString::ToString(num)){}MoonBigNum::MoonBigNum(const MoonBigNum &MoonBigNum){ this->numStr = MoonBigNum.numStr;}MoonBigNum::~MoonBigNum(void){}const string &MoonBigNum::Value()const{ return numStr;}const MoonBigNum MoonBigNum::operator+(const MoonBigNum &right)const{ string result; string::const_reverse_iterator it1 = this->numStr.rbegin(); string::const_reverse_iterator it2 = right.numStr.rbegin(); UINT32 currValue = 0; UINT32 lastFlag = 0; bool notEnd = true; while(true) { currValue = 0; notEnd = false; if(lastFlag != 0) { ++currValue; notEnd = true; } lastFlag = 0; if(it1 != this->numStr.rend()) { currValue += *it1 - '0'; notEnd = true; ++it1; } if(it2 != right.numStr.rend()) { currValue += *it2 - '0'; notEnd = true; ++it2; } if(!notEnd) { break; } if(currValue >= 10) { lastFlag = 1; currValue -= 10; } result += currValue + '0'; } return MoonBigNum(MoonString::Reverse(result));}bool MoonBigNum::operator==(const MoonBigNum &right) const{ return this->numStr == right.numStr;}bool MoonBigNum::operator<(const MoonBigNum &right) const{ return this->numStr < right.numStr;}bool MoonBigNum::operator>(const MoonBigNum &right) const{ return right < *this;}MoonBigNum MoonBigNum::operator++(){ *this = *this + MoonBigNum(1); return *this;}MoonBigNum MoonBigNum::operator++(int){ MoonBigNum result(*this); *this = *this + MoonBigNum(1); return result;}MoonBigNum MoonBigNum::Reverse() const{ return MoonBigNum(MoonString::Reverse(numStr));}MoonBigNum MoonBigNum::operator+=(MoonBigNum &right){ *this = *this + right; return *this;}MoonBigNum MoonBigNum::operator+=(UINT32 num){ *this += MoonBigNum(num); return *this;}
#pragma once#include <string>#include <sstream>using namespace std;class MoonString{public: //************************************ // Method: Reverse // Access: public static // Describe: 字串逆序 // Parameter: const string & srcString 要逆序的字串 // Returns: std::string 逆序結果 //************************************ static string Reverse(const string &srcString); //************************************ // Method: ToString // Access: public static // Describe: 任意類型轉換為string // Parameter: T value // Returns: std::string //************************************ template <class T> static const string ToString(T value);};template <class T>const string MoonString::ToString( T value ){ stringstream ss; ss<<value; string result; ss>>result; return result;}
#include "MoonString.h"string MoonString::Reverse(const string &srcString){ size_t len = srcString.length(); string outString; for(size_t i = 0; i < len; ++i) { outString += srcString[len - i - 1]; } return outString;}
// Lychrel numbers// Problem 55// If we take 47, reverse and add, 47 + 74 = 121, which is palindromic.//// Not all numbers produce palindromes so quickly. For example,//// 349 + 943 = 1292,// 1292 + 2921 = 4213// 4213 + 3124 = 7337//// That is, 349 took three iterations to arrive at a palindrome.//// Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, 10677 is the first number to be shown to require over fifty iterations before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits).//// Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is 4994.//// How many Lychrel numbers are there below ten-thousand?//// NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.//// 題目55:10000以下有多少Lychrel數?// 我們將47與它的逆轉相加,47 + 74 = 121, 可以得到一個迴文。//// 並不是所有數都能這麼快產生迴文,例如://// 349 + 943 = 1292,// 1292 + 2921 = 4213// 4213 + 3124 = 7337//// 也就是說349需要三次迭代才能產生一個迴文。//// 雖然還沒有被證明,人們認為一些數字永遠不會產生迴文,例如196。那些永遠不能通過上面的方法(逆轉然後相加)產生迴文的數字叫做Lychrel數。因為這些數位理論本質,同時也為了這道題,我們認為一個數如果不能被證明的不是Lychrel數的話,那麼它就是Lychre數。此外,對於每個一萬以下的數字,你還有以下已知條件:這個數如果不能在50次迭代以內得到一個迴文,那麼就算用盡現有的所有運算能力也永遠不會得到。10677是第一個需要50次以上迭代得到迴文的數,它可以通過53次迭代得到一個28位的迴文:4668731596684224866951378664。//// 令人驚奇的是,有一些迴文數本身也是Lychrel數,第一個例子是4994。//// 10000以下一共有多少個Lychrel數?#include <iostream>#include <windows.h>#include <ctime>#include <vector>#include <string>#include <sstream>#include <algorithm>#include <assert.h>#include "MoonBigNum.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");}/*************************解題開始*********************************/void TestFun1(){ cout << "TestFun1 OK!" << endl;}inline bool IsPalindromeNum(const MoonBigNum &bigNum){ return bigNum == bigNum.Reverse();}//************************************// Method: IsLychrelNum// Access: public// Describe: 判斷是否是Lychrel數// Parameter: UINT32 num// Returns: bool//************************************bool IsLychrelNum(UINT32 num){ const UINT32 MAX_LOOP = 50; // 最多加50次 MoonBigNum bigNum(num); for(UINT32 i = 0; i < MAX_LOOP; ++i) { bigNum += bigNum.Reverse(); if(IsPalindromeNum(bigNum)) { return false; } } return true;}void F1(){ cout << "void F1()" << endl; // TestFun1(); DetailPrinter detailPrinter; detailPrinter.Start(); /*********************************演算法開始*******************************/ const UINT32 MAX_NUM = 10000; UINT32 lychrelNumCount = 0; for(UINT32 i = 1; i < MAX_NUM; ++i) { if(IsLychrelNum(i)) { ++lychrelNumCount; }// else// {// cout << i << endl;// } } cout << MAX_NUM << "以內的Lychrel數有" << lychrelNumCount << "個" << endl; /*********************************演算法結束*******************************/ detailPrinter.End();}//主函數int main(){ F1(); return 0;}/*void F1()10000以內的Lychrel數有249個Total Milliseconds is 4411.78By GodMoonSun Jun 2 18:46:29 2013*/