1. 程式人生 > 其它 >LeetCode-372 超級次方

LeetCode-372 超級次方

題目來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/super-pow/submissions/

題目描述

你的任務是計算ab對1337 取模,a 是一個正整數,b 是一個非常大的正整數且會以陣列形式給出。

示例 1:

輸入:a = 2, b = [3]
輸出:8


示例 2:

輸入:a = 2, b = [1,0]
輸出:1024


示例 3:

輸入:a = 1, b = [4,3,3,8,5,2]
輸出:1


示例 4:

輸入:a = 2147483647, b = [2,0,0]
輸出:1198

提示:

1 <= a <= 231 - 1
1 <= b.length <= 2000
0 <= b[i] <= 9
b 不含前導 0

解題思路

拿到題目先不急著寫程式碼,首先來分析。

b是一個非常大的數字,大到必須要用vector來儲存,ab肯定不是直接暴力求解可以求出的。

由數學知識可知,取模運算符合結合律,即(a * b)Mod c = ((a Mod c) * (b Mod c)) Mod c.在次方的運算過程中邊取模邊計算,數字會小得多。

那麼,現在問題轉換為如何將ab拆分,使得次方更好算。

由題目得 ,其中 m 為 b陣列的長度。

我們這裡先看指數部分,設 那麼,可得,我們可以得到了一個關於n的遞推公式。

帶入原式,就可以得到關於a的遞推公式:

根據以上遞推公式,就可以依次遍歷陣列b求解

原始碼展示

class
Solution { public: int Loc_Pow(int a, int b) { int iBase = a, iRet = 1; while(b) { if(b % 2) iRet = ((long)iRet * iBase) % 1337; iBase = ((long)iBase * iBase) % 1337; b /= 2; } return iRet; }
int superPow(int a, vector<int>& b) { int iRet = 1; for(auto iter : b) iRet = Loc_Pow(iRet, 10) * Loc_Pow(a, iter) % 1337; return iRet; } };

執行結果