題目描述:
給你乙個非零整數,讓你求這個數的n次方,每次相乘的結果可以在後面使用,求至少需要多少次乘。
如24:2*2=22(第一次乘),22*22=24(第二次乘),所以最少共2次。
211:2*2=22(第一次乘),22*22=24(第二次乘)24*24=28(第三次乘)28*22=210(第四次乘)210*21=211(第五次乘)所以最少共5次。
輸入第一行m表示有m(1<=m<=100)組測試資料;
每一組測試資料有一整數n(0
輸出輸出每組測試資料所需次數s;
樣例輸入
樣例輸出
解題方法:
每次尋找小於等於n的最大的2k的值,如11,先找23=8,然後以此類推。
則可以轉換為二進位制計算。
其演算法類似於把乙個十進位制數轉換為二進位制。只要把最高位1轉換的次數記下來,再加上這個二進位制其它為1的位的個數。例如:
(14)10=(1110)2
最高位的1需要轉換3次,所以計算14次方需要3+2(其它為1的位數)=5次。
(100)10=(1100100)2
最高位的1需要轉換6次,所以計算100次方需要6+2(其它為1的位數)=8次。
此演算法關鍵在於最高位1轉換的次數。(2倍增長是速度最快!)只要算出最高位的1,則低位的1已經被全部算出。因為最高位的1是通過1+1=2 2+2=4 4+4=8 8+8=16……算出來的,則最高位轉換次數算出後,其他為1的位只是在使用的時候加一次。(二分思想)
**如下:
#include#includeusing namespace std; int count(int num) //求乙個數二進位制位中有幾個一 return i; } int main() { int n; cin>>n; while(n--) { int num, res; cin>>num; res = log((double)num) / log(2.0); //求最高位1的轉換次數 cout<<(int)res + count(num) - 1<
最小乘法次數
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 給你乙個非零整數,讓你求這個數的n次方,每次相乘的結果可以在後面使用,求至少需要多少次乘。如24 2 2 22 第一次乘 22 22 24 第二次乘 所以最少共2次 第一行m表示有m 1 m 100 組測試資料 每一組測試資料有一整數...
NYOJ 46最小乘法次數
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 給你乙個非零整數,讓你求這個數的n次方,每次相乘的結果可以在後面使用,求至少需要多少次乘。如24 2 2 22 第一次乘 22 22 24 第二次乘 所以最少共2次 輸入 第一行m表示有m 1 m 100 組測試資料 每一組測試...
最小乘法 DP
如果在乙個正整數中間插入一些乘號,會得到乙個更小的數字。乙個數字有不同的插入方法,會得到不同的數字,我們想知道最大的那個數字是多少?例如 233 得到 69,1111 得到 121 拿到題目會發現這道題和矩陣鏈相乘非常相似,以至於我上來就按照矩陣鏈乘法那樣設定狀態 啊啊啊思維定式了 即dp i j ...