// Self powers
// Problem 48
// The series, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317.
//
// Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000.
#include <iostream>
#include <windows.h>
#include <ctime>
#include <assert.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");
}
/*************************解题开始*********************************/
const UINT64 MAX_TEN_NUM = 10000000000;
//************************************
// Method: LastTenDigitAdd
// Access: public
// Describe: 大数相加,截取低10位
// Parameter: UINT64 num1
// Parameter: UINT64 num2
// Returns: UINT64
//************************************
inline UINT64 LastTenDigitAdd(UINT64 num1, UINT64 num2)
{
return (num1 % MAX_TEN_NUM + num2 % MAX_TEN_NUM) % MAX_TEN_NUM;
}
//************************************
// Method: LastTenDigitMulti
// Access: public
// Describe: 大数相乘,截取低10位
// Parameter: UINT64 num1
// Parameter: UINT64 num2
// Returns: UINT64
//************************************
UINT64 LastTenDigitMulti(UINT64 num1, UINT64 num2)
{
const UINT32 RADIO = 10;
UINT64 result = 0;
num1 %= MAX_TEN_NUM;
num2 %= MAX_TEN_NUM;
UINT32 currDigit = 0;
UINT64 currResult = 0;
int count = 0;
UINT64 removeZeros = 0; // num%removeZero去除前面多余的位数
UINT64 addZeros = 0; // 去除后在末尾补上0
while(num2 != 0)
{
currDigit = num2 % RADIO;
++count;
removeZeros = (UINT64)pow((double)RADIO, 10 - count + 1);
addZeros = (UINT64)pow((double)RADIO, count - 1);
currResult = num1 * currDigit % removeZeros * addZeros;
result = LastTenDigitAdd(result, currResult);
num2 /= RADIO;
}
return result;
}
//************************************
// Method: GetSelfPower
// Access: public
// Describe: 获取num^num
// Parameter: UINT32 num
// Returns: UINT64
//************************************
UINT64 GetSelfPower(UINT32 num)
{
UINT64 result = num;
for(UINT32 i = 1; i < num; ++i)
{
result = LastTenDigitMulti(result, num);
}
return result;
}
void TestFun1()
{
UINT64 result = 0;
result = LastTenDigitAdd(9999999999, 1);
assert(result == 0);
result = LastTenDigitAdd(1234567890, 1234567890);
assert(result == 2469135780);
result = LastTenDigitAdd(9876543210, 1234567890);
assert(result == 1111111100);
result = LastTenDigitAdd(99876543210, 1234567890);
assert(result == 1111111100);
result = LastTenDigitAdd(111111111111111, 789456123078541);
assert(result == 7234189652);
result = LastTenDigitMulti(12345678, 321654);
assert(result == 1036711412);
result = LastTenDigitMulti(12345678, 0);
assert(result == 0);
result = LastTenDigitMulti(0, 321654);
assert(result == 0);
result = LastTenDigitMulti(1234567890123, 1);
assert(result == 4567890123);
result = GetSelfPower(1);
assert(result == 1);
result = GetSelfPower(10);
assert(result == 0);
result = GetSelfPower(3);
assert(result == 27);
result = GetSelfPower(8);
assert(result == 16777216);
result = GetSelfPower(9);
assert(result == 387420489);
result = GetSelfPower(1000);
assert(result == 0);
cout << "Test OK!" << endl;
}
void F1()
{
cout << "void F1()" << endl;
// TestFun1();
DetailPrinter detailPrinter;
detailPrinter.Start();
/*********************************算法开始*******************************/
UINT32 BEGIN_NUM = 1;
UINT32 END_NUM = 1000;
UINT64 lastTenDigitOfSum = 0;
for(UINT32 i = BEGIN_NUM; i <= END_NUM; ++i)
{
lastTenDigitOfSum = LastTenDigitAdd(lastTenDigitOfSum, GetSelfPower(i));
}
cout << "The last ten digit of sum is " << lastTenDigitOfSum << endl;
/*********************************算法结束*******************************/
detailPrinter.End();
}
//主函数
int main()
{
F1();
return 0;
}
/*
void F1()
The last ten digit of sum is 9110846700
Total Milliseconds is 455.337
By GodMoon
Mon Mar 11 22:30:36 2013
*/
【ProjectEuler】ProjectEuler_048
最新推荐文章于 2019-08-12 22:44:46 发布