【ProjectEuler】ProjectEuler_024

// Problem 24
// 16 August 2002
//
// A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
//
// 012   021   102   120   201   210
//
// What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

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

// 求某個數的階乘
long Factorial(long num)
{
    if(num <= 1)
    {
        return 1;
    }
    else
    {
        return num * Factorial(num - 1);
    }
}

// 尋找numCount個從0開始的數排列起來第numRemaind個數的首位
// 然後從numRemaindArray中找到從小到大的剩餘數作爲首位
// 例如:
// numCount=3,numRemaind=4;
// 排列爲:012,021,102,120,201,210
// 第四個數爲120,則首位爲1
// numRemaind表示查找到的數在這單位數中處於第幾個,從1開始,最大爲unitNum
int FindTheFirstNum(int *numRemaindArray, const int numCount , int &numRemaind)
{
    //獲取每單位包含多少個數
    int unitNum = Factorial(numCount - 1);

    //numRemaind必小於總數
    assert(numRemaind <= unitNum * numCount);

    int index = (numRemaind - 1) / unitNum;

    //獲取剩餘數,如果剛好整除,則在此單位數的最後一個,第unitNum個
    numRemaind = numRemaind % unitNum;

    if(numRemaind == 0)
    {
        numRemaind = unitNum;
    }

    //獲取結果的數字
    int result = numRemaindArray[index];

    //後面的數提前
    for(int i = index + 1; i < numCount; i++)
    {
        numRemaindArray[i - 1] = numRemaindArray[i];
    }

    //最後置0
    numRemaindArray[numCount - 1] = 0;

    return result;
}

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

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

    const int NUM_COUNT = 10;		//總共的數字
    const int INDEX_NUM = 1000000;		//要尋找數字的位置

    int numRemaindArray[NUM_COUNT];	//剩餘數的數組

    //初始化
    for(int i = 0; i < NUM_COUNT; i++)
    {
        numRemaindArray[i] = i;
    }

    int numRemaind = INDEX_NUM;

    cout << "在0-" << NUM_COUNT - 1 << "這" << NUM_COUNT << "個數字從小到大的排列中,第" << INDEX_NUM << "個爲:";

    for(int i = NUM_COUNT; i > 0; i--)
    {
        cout << FindTheFirstNum(numRemaindArray, i, numRemaind);
    }

    cout << endl;

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

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

/*
void F1()
在0-9這10個數字從小到大的排列中,第1000000個爲:2783915460
Total Milliseconds is 17.0488

By GodMoon
*/

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