【ProjectEuler】ProjectEuler_030

// Problem 30
// 08 November 2002
//
// Surprisingly there are only three numbers that can be written as the sum of fourth powers of their digits:
//
// 1634 = 14 + 64 + 34 + 44
// 8208 = 84 + 24 + 04 + 84
// 9474 = 94 + 44 + 74 + 44
// As 1 = 14 is not a sum it is not included.
//
// The sum of these numbers is 1634 + 8208 + 9474 = 19316.
//
// Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.

#include <iostream>
#include <windows.h>
using namespace std;

// 求某數的5次冪
inline int FivePowers(const int num)
{
    return num * num * num * num * num;
}

// 求某數每個數字的五次冪之和
int SumOfDigitFivePower(int num)
{
    int digitSum = 0;

    while(num != 0)
    {
        digitSum += FivePowers(num % 10);
        num /= 10;
    }

    return digitSum;
}

void F1()
{
    cout << "void F1()" << endl;

    LARGE_INTEGER timeStart, timeEnd, freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&timeStart);

    int digitSum = 0;
    int sum = 0;

    const int MAX_NUM = 1000000;		//自己設的上限1000000,我還不知道如何判斷具體的上限,所以隨意設的,效率較低

    for(int i = 2; i < MAX_NUM; i++)		//i從2開始,排除1
    {
        digitSum = SumOfDigitFivePower(i);

        if(digitSum == i)
        {
            cout << i << '+';
            sum += i;
        }
    }

    cout << "\b=" << sum << endl;		//用"\b"消除上面那個'+'號

    QueryPerformanceCounter(&timeEnd);
    cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;
}

// 求某數每個數字的五次冪之和放在digitSum裏,count記錄次數的位數返回,用於判斷結束點
int SumOfDigitFivePower(int num, int &digitSum)
{
    int count = 0;
    digitSum = 0;

    while(num != 0)
    {
        digitSum += FivePowers(num % 10);
        num /= 10;
        count++;
    }

    return count;
}

void F2()
{
    cout << "void F2()" << endl;

    LARGE_INTEGER timeStart, timeEnd, freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&timeStart);

    int digitSum = 0;
    int sum = 0;

    //9的5次冪,本來自己設的上限10000000,我還不知道如何判斷具體的上限,所以隨意設的,效率較低
    //後面看到別人的想法才知道每個數字能表示的最大的值是59049,所以當數字小於它的位數*59049時,就可以結束循環了,提高了3倍左右的效率
    const int MAX_NUM_PER_DIGIT = 59049;

    for(int i = 2; i < SumOfDigitFivePower(i, digitSum) * MAX_NUM_PER_DIGIT; i++)		//i從2開始,排除1
    {
        if(digitSum == i)
        {
            cout << i << '+';
            sum += i;
        }
    }

    cout << "\b=" << sum << endl;		//用"\b"消除上面那個'+'號

    QueryPerformanceCounter(&timeEnd);
    cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;
}

//主函數
int main()
{
    F2();
    return 0;
}

/*
void F1()
4150+4151+54748+92727+93084+194979=443839
Total Milliseconds is 522.396

void F2()
4150+4151+54748+92727+93084+194979=443839
Total Milliseconds is 177.629

By GodMoon
2011年11月2日21:51:04
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章