#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.78
By GodMoon
Sun Jun 2 18:46:29 2013
*/