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

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