【ProjectEuler】ProjectEuler_029

// Problem 29
// 25 October 2002
//
// Consider all integer combinations of ab for 2  a  5 and 2  b  5:
//
// 22=4, 23=8, 24=16, 25=32
// 32=9, 33=27, 34=81, 35=243
// 42=16, 43=64, 44=256, 45=1024
// 52=25, 53=125, 54=625, 55=3125
// If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:
//
// 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
//
// How many distinct terms are in the sequence generated by ab for 2 <= a <= 100 and 2 <= b <= 100?

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

// 获取某个数特定的信息
// 信息是它是否是m的n次幂(n>=2),如果是,在numInfo中返回数组{m,n},如果不是,则直接返回{0,0}
// 当然,这个方法有其局限性,因为100以内的所有特定的值是很少的,可以求出来,此处人为构造了这么个数据结构,适应性降低了,这是这个解法的缺点
void GetSpeInfo(const int num, int *numInfo)
{
    //100以内的所有是m的n次幂的所有可能,如果有16=2^4=4^2,取底数小的数(16=2^4),以便记录
    static int speNum[][3] = {{4, 2, 2}, {9, 3, 2}, {16, 2, 4}, {25, 5, 2}, {36, 6, 2}, {49, 7, 2}, {64, 2, 6}, {81, 3, 4}, {100, 10, 2}, {8, 2, 3}, {27, 3, 3}, {32, 2, 5}};
    int dimSize2 = sizeof(speNum[0]) / sizeof(int);			//二维大小,此处为3
    int dimSize1 = sizeof(speNum) / sizeof(int) / dimSize2;	//一维大小,此处为12

    for(int i = 0; i < dimSize1; i++)
    {
        if(speNum[i][0] == num)
        {
            numInfo[0] = speNum[i][1];
            numInfo[1] = speNum[i][2];
            return;
        }
    }

    numInfo[0] = numInfo[1] = 0;
}

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

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

    const int MAX_NUM = 100;
    const int MIN_NUM = 2;
    bool numFlag[1000][1000] = {false};			//记录所有的数是否经过计算,Bit Map,局部变量记得初始化,上限取1000,其实此处取601即可,因为2^6已经是64了,最大只能到6,6*100=600

    int sum = 0;
    int numInfo[2] = {0};

    for(int i = MIN_NUM; i <= MAX_NUM; i++)			//遍历所有的数
    {
        GetSpeInfo(i, numInfo);						//获取数的幂次信息

        if(numInfo[0] == 0)								//如果不是某个数的幂,则直接记录
        {
            for(int j = MIN_NUM; j <= MAX_NUM; j++)
            {
                numFlag[i][j] = true;
                sum++;
            }
        }
        else											//如果是某个数的幂,查询是否已经记录过这个数,如果有,则跳过,没有则记录
        {
            for(int j = MIN_NUM; j <= MAX_NUM; j++)
            {
                if(!numFlag[numInfo[0]][j * numInfo[1]])
                {
                    numFlag[numInfo[0]][j * numInfo[1]] = true;
                    sum++;
                }
            }
        }
    }

    cout << "总共有" << sum << "个不同的数" << endl;

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

//主函数
int main()
{
    F1();
    return 0;
}

/*
void F1()
总共有9183个不同的数
Total Milliseconds is 4.78914

By GodMoon
2011年11月2日21:00:39
*/

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