1. 程式人生 > >快速冪演算法(hdu) Rightmost Digit

快速冪演算法(hdu) Rightmost Digit

快速冪演算法,顧名思義,就是進行冪運算,http://acm.hdu.edu.cn/showproblem.php?pid=1061
這是hdu經典的一道題,如果我在接下來的解析中寫的不好,也請大家指點。
hdu這道題,他要求我們算出每個正整數的個位數,
這裡寫圖片描述
這裡我先上程式碼,按題要求,我們先輸入t,即接下去我們要進行測試t個例子,t– 的同時我們輸入我們要取個位的數字,然後列印go,重點來咯,go自定義函式,就是進行取模運算的關鍵,因為無論輸入什麼數字,我們取模後他的個位都不會發生變化,因此,我們在開頭就定義了一個a,先將他取模,這樣,更是減少了演算法的複雜度,b就是a的b次,while(b)相當於當b!=0的時候,也就是當b次不為0時,我們就可以進行冪運算啦,這裡寫圖片描述


從這個圖片就能看出,當為奇數的時候,他會剩下最後一個單獨的A,因此ans=(ans*a)%10就由此得出,這句話就是進行奇數運算的時候所要進行的,最後(a*a)%c ,a*a就是要求進行的b次運算,最後取模,得到個位數,進行到n-2次的時候 b因為b/2變為1,得出b次的最後一個個位數,這是回到if (b % 2 == 1) ans = (ans*a) % c;  得出最後一個個位數,返回到主函式main中,就可以得出答案拉。
另外,在這裡指出一個小技巧,當我們進行b次相乘取模的時候,我們會有趣的發現,在我們算出幾個餘數之後,接下去的餘數會無限有迴圈的計算下去。例如2%10=2,(2*2)%10=4,(2*2*2)%10=8,(2*2*2*2)%10=16,(2*2*2*2*2)%10=2
,(2*2*2*2*2*2)%10=4.。。。。。。。
另外還有遞迴進行的冪演算法,
int qpow(int a,int n)  
{  
    if(n == 0) return 1;  
    int half = qpow(a,n/2);  
    if(n%2)  
        return half*half*a;  
    return half*half;  
}  
  
int main()  
{  
    printf(“%d\n”, qpow(2,10));  
    return 0;  
}  。