第二個板子!!!(第一個板子還沒發)
有那么一種算法可以讓計算a^b變得更快,那就是快速冪。如果直接暴力計算的話需要計算b次。時間蠻長的。
題目描述:
輸入a,b.(a,b為整數)計算a^b。
輸入輸出格式
輸入格式:
兩個整數a、b。.
輸出格式:
輸出“a^b=s”
s為運算結果
前提:你需要了解二進制,十進制。位運算的知識(當然也可以沒有,萬事皆可模擬。)
沒有位運算的:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<iomanip> #include<queue> #include<cmath> using namespace std; char e[10001]; int cd; long long quickpow(long long a,char b[]) { long long ans=1,base=a; while(cd!=-1) { if(int(b[cd])!=0) ans*=base;//最后一位是1的話。 base*=base; cd--;//抹去最后一位。 } return ans; } void zh(long long a) { char zs[10001]; int sum=0; while(a!=0) { zs[sum]=a%2; a/=2; sum++; } sum--; int js=sum; cd=sum;//轉換為二進制后的最后一個元素的位置。如(10)10=(1010)2最后一個元素的位置為三。 for(int i=0;i<=sum;++i) { e[js]=zs[i]; js--; } } int main() { long long a,b; cin>>a>>b; zh(b);//將b轉換為二進制。 cout<<quickpow(a,e); return 0; }
代碼:
//省略...... long long quickpow(long long a,long long b) { long long ans=1,base=a; while(b!=0) { if(b&1!=0) ans*=base; base*=base; b>>=1; //將b的二進制數向右移一位(相當於將b的二進制數的最后一位抹掉。) } return ans; }
PS:不用位運算的代碼當指數為零時需要特判!
注意:因為是乘方運算所以很有可能會爆long long!
input:
2 11
output:
2048
先講一下(&、>>)位運算.
&:‘&’叫做按位與。作用:把參與運算的兩個數對應的二進制相與,只有對應的二進制均為1時,結果(應該也是二進制的形式)的對應位才為1,否則為0。
>>:'>>'叫做右移。作用:把“>>”左邊的運算數的各二進制位全部右移若干位(“>>”右邊的那個數)。
以此樣例講一下吧。
(11)10=(1011)2。
如何將二進制轉換為十進制那?
醬紫,1*20 +1*21 (+0*22) +1*23。
∴211=2(1*20 +1*21 (+0*22) +1*23)。
小學我們學過 an*am=an+m。
∴211=21*22*28。
快速冪就是這樣計算的!
模擬一下樣例:
ans=1,base=2。
11的二進制數為1011,不為0 進行循環直到為0。
1011的最后一位為1,ans*base。
若不為1,就不進行ans*base。
base*base,就是由2變成了4(2^2)。
1011抹去最后一位直到為0.
就是醬紫。