【ProjectEuler】ProjectEuler_055(10000以下有多少Lychrel數?)

來源:互聯網
上載者:User
#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*/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.