題目88:漢諾塔(一)

題目鏈接:

http://acm.nyist.net/JudgeOnline/problem.php?pid=88

描述

在印度,有這麼一個古老的傳說:在世界中心貝拿勒斯(在印度北部)的聖廟裏,一塊黃銅板上插着三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有一個僧侶在按照下面的法則移動這些金片:一次只移動一片,不管在哪根針上,小片必須在大片上面。僧侶們預言,當所有的金片都從梵天穿好的那根針上移到另外一根針上時,世界就將在一聲霹靂中消滅,而梵塔、廟宇和衆生也都將同歸於盡。

現在請你計算出起始有m個金片的漢諾塔金片全部移動到另外一個針上時需要移動的最少步數是多少?(由於結果太大,現在只要求你算出結果的十進制位最後六位)

輸入

第一行是一個整數N表示測試數據的組數(0

輸出

輸出把金片起始針上全部移動到另外一個針上需要移動的最少步數的十進制表示的最後六位。

樣例輸入

2
1
1000

樣例輸出

1
69375

算法思想:

首先考慮m個金片總共最少需要移動多少次,f(n) = 2 * f(n - 1) + 1,f(1) = 1。故從遞推式中可以得出f(n) = 2^n - 1。但由於輸入的n很大,故普通運算會超時,因此需要快速計算2^n的方法,可以考慮使用類似二分法的方法來解決,如:a^(2 * m) = a^m * a^m ,a^m = (a^(m/2) ) * (a^(m/2) ),這樣時間複雜度就爲logn了。

源代碼

#include <iostream>
using namespace std;
long long powMod(long long a,long long b,long long c)
{
    long long result = 1;
    while (b > 0)
    {
        if (b % 2 == 1)
            result = result * a % c;
        b /= 2;
        a = a * a % c;
    }
    return result;
}
int main()
{
    int N, m;
    cin >> N;
    while (N--)
    {
        cin >> m;
        cout << powMod(2, m, 1000000) - 1 << endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章