【ProjectEuler】ProjectEuler_023

来源:互联网 发布:汽车电脑调音软件 编辑:程序博客网 时间:2024/06/11 05:03
// Problem 23// 02 August 2002//// A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.//// A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.//// As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.//// Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.#include <iostream>#include <windows.h>#include <set>using namespace std;//数的上限const int MAX_NUM = 28123;//记录上限内的所有丰富数,数组是用空间换取时间set<int> allAbundantNum;//获取某数的和数之和int GetSumOfDivisors(const int num){    int sum = 0;    for(int i = num / 2; i >= 1; i--)    {        if(num % i == 0)        {            sum += i;        }    }    return sum;}//判断某数是否能表示为2个丰富数之和//可以则返回true,否则返回falsebool CanSumNum1(const int num){    //另一个数    int anotherNum = 0;    for(set<int>::iterator it = allAbundantNum.begin(); it != allAbundantNum.end(); it++)    {        //获取另一个数        anotherNum = num - *it;        //排除小于0的结果        if(anotherNum < 0)        {            break;        }        //能表示为2个丰富数之和则返回true        if(allAbundantNum.find(anotherNum) != allAbundantNum.end())        {            return true;        }    }    return false;}//方法1//先获取所有的丰富数,然后遍历1到MAX_NUM,在丰富数内查找(MAX_NUM-丰富数),如果找到,则说明它是2个丰富数之和void F1(){    cout << "void F1()" << endl;    LARGE_INTEGER timeStart, timeEnd, freq;    QueryPerformanceFrequency(&freq);    QueryPerformanceCounter(&timeStart);    //获取所有的丰富数    for(int i = 1; i <= MAX_NUM; i++)    {        if(GetSumOfDivisors(i) > i)        {            allAbundantNum.insert(i);        }    }    int totalResult = 0;    for(int i = 1; i <= MAX_NUM; i++)    {        if(!CanSumNum1(i))        {            totalResult += i;        }    }    cout << "结果为:" << totalResult << endl;    QueryPerformanceCounter(&timeEnd);    cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;}//方法2用到的丰富数数组,因为是全局变量,系统默认全部初始化为falsebool allAbundantNumberArray[MAX_NUM + 1] ;//判断某数是否能表示为2个丰富数之和//可以则返回true,否则返回falsebool CanSumNum2(const int num){    //另一个数    int anotherNum = 0;    for(set<int>::iterator it = allAbundantNum.begin(); it != allAbundantNum.end(); it++)    {        //获取另一个数        anotherNum = num - *it;        //排除小于0的结果        if(anotherNum < 0)        {            break;        }        //能表示为2个丰富数之和则返回true        if(allAbundantNumberArray[num - *it])        {            return true;        }    }    return false;}//方法2//和方法1类似,只不过这个方法多了一个bool数组,用于记录丰富数的位置,数组可以随机查找,会比set容器的顺序查找速度快void F2(){    cout << "void F2()" << endl;    LARGE_INTEGER timeStart, timeEnd, freq;    QueryPerformanceFrequency(&freq);    QueryPerformanceCounter(&timeStart);    //获取所有的丰富数    for(int i = 1; i <= MAX_NUM; i++)    {        if(GetSumOfDivisors(i) > i)        {            allAbundantNum.insert(i);            allAbundantNumberArray[i] = true;        }    }    allAbundantNumberArray[0] = false;    int totalResult = 0;    for(int i = 1; i <= MAX_NUM; i++)    {        if(!CanSumNum2(i))        {            totalResult += i;        }    }    cout << "结果为:" << totalResult << endl;    QueryPerformanceCounter(&timeEnd);    cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;}//方法3//先获取所有的丰富数,再把它们之间不同的数相加,在一个数组中置true,最后读取所有为false的位置相加即可。void F3(){    cout << "void F3()" << endl;    LARGE_INTEGER timeStart, timeEnd, freq;    QueryPerformanceFrequency(&freq);    QueryPerformanceCounter(&timeStart);    //获取所有的丰富数    for(int i = 1; i <= MAX_NUM; i++)    {        if(GetSumOfDivisors(i) > i)        {            allAbundantNum.insert(i);        }    }    bool allAvailableNum[MAX_NUM + 1] = {false};    //跳出标志位    bool flag = false;    for(set<int>::iterator it1 = allAbundantNum.begin(); it1 != allAbundantNum.end(); it1++)    {        for(set<int>::iterator it2 = it1; it2 != allAbundantNum.end(); it2++)        {            //超出范围跳出            if(*it1 + *it2 > MAX_NUM)            {                break;            }            allAvailableNum[*it1 + *it2] = true;        }        //不管怎么样都会超出范围,跳出        if((*it1 << 1) > MAX_NUM)        {            break;        }    }    int totalResult = 0;    for(int i = 1; i <= MAX_NUM; i++)    {        if(!allAvailableNum[i])        {            totalResult += i;        }    }    cout << "结果为:" << totalResult << endl;    QueryPerformanceCounter(&timeEnd);    cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;}//主函数int main(){    F2();    return 0;}/*void F1()结果为:4179871Total Milliseconds is 69315.5void F2()结果为:4179871Total Milliseconds is 20888.3void F3()结果为:4179871Total Milliseconds is 60706.5By GodMoon*/

原创粉丝点击