#17610: 求救,感謝教學


happyman940815@gmail.com (【百鬼組】希格瑪 - 一位排球廢物高中生)

學校 : 臺北市私立延平高級中學
編號 : 69013
來源 : [115.43.155.126]
最後登入時間 :
2023-08-11 16:12:40
d468. 简单求幂题(求幂系列题3) -- scientific | From: [106.105.30.190] | 發表日期 : 2019-04-27 18:37

#include <iostream>
#include <cmath>
using namespace std;
long long int pw(long long int a, long long int n)
{
 int sum=a;
 if(n==0){
  return 1;
 }
 for(int i=0; i<(n-1); i++)
 {
  sum*=a;
 }
 return sum;
}

main()
{
string s;
long long int a,n;
long long int d;
while(cin>>a>>s)
{
if(a==0 && s=="0"){
cout<<"All Over.\n";
break;
}
else{
n=0;
for(int i=0; i<s.size(); i++)
{
n+=(s[s.size()-i-1]-48)*pw(10,i);
}
d=pw(a,n);
cout<<d<<'\n';
}
}
}

怎麼解....求救,為什麼我跑出這個奇怪的數字

快速冪解法是什麼意思,上網查都看不懂

您的答案為: -1112319212
正確答案為: 727009963485125396
 
#17611: Re:求救,感謝教學


inversion (「我們所認識的可符香是個像天使的好女孩」之葉林 *Cries...)

學校 : 國立清華大學
編號 : 43537
來源 : [49.159.6.107]
最後登入時間 :
2022-05-28 19:29:12
d468. 简单求幂题(求幂系列题3) -- scientific | From: [49.158.83.43] | 發表日期 : 2019-04-27 19:24

首先,在您宣告的 pw() 函式裡,sum 這個變數的型態為 int , int 能容納的範圍為 -231 ~ 231 - 1 , 不夠容納題目所求的 -263 ~ 263 - 1 (會發生溢位(overflow),因而造成您的答案出現負值)。

改成 long long 即可。

 

接著,所謂的「快速冪」可從以下性質觀察而出:

已知,ab × ac = ab + c ,而任意一正整數皆可表示為二進位數字,如 42(10) = 101010(2) 

因此我們可以利用這個性質將任意次方之值分解為 2 的冪次之和,例如 1042 = 1032 + 8 + 2 ,而就可以進一步拆解為 1032 × 108 × 102 

而因為現在的次方之數值皆為 2 的冪次,因此可以快速地藉由自己乘自己而得到 10 → 102 → 104 → 108 → 1016 …… 最後將相應的次方相乘,即可以得到所求。

此即為——「快速冪」。

 

像是 1042,本來應該要做 41 次的乘法。套用快速冪的技巧,可以將乘法次數縮減到 8 次。次方越大,縮減次數的比率越大。

假設要求某數的 n 次方,一般作法為 n - 1 次乘法運算;而快速冪只需約莫 log2(n) 次乘法。

 

以上,希望有幫助到您。

 
ZeroJudge Forum