【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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值