PDF文件公眾號回覆關鍵字:20241012
此前解析題,P8813 [CSP-J 2022] 乘方,給出了迴圈的解題思路,當時在洛谷提交是透過的,後臺收到留言,a=1,b=1e9會炸吧?,確實啊整除要求1s內迴圈次數最大可以到10^7,現在測試資料明顯大很多,按測試資料有這個可能,沒想到CSP普及組第1題竟然翻車,去CCF官網去找測試資料,竟然沒有2022年的測試資料,去另外一個OJ上面測試了一下,竟然有超時測試用例
提交原碼
#include<bits/stdc++.h>
using namespace std;
const int N=1e9;//允許的最大值 超出輸出-1
int a,b;//輸入a b
long long m=1;//儲存 a^b
int main(){
cin>>a>>b;//輸入a b
for(int i=0;i<b;i++){//迴圈b次
m=m*a;//m從1開始每次乘以a
if(m>N){//如果大於允許的最大值 輸出-1
cout<<"-1";
return 0;//退出程式
}
}
cout<<m;//輸出 a^b
return 0;
}
分析
確實a=1的時候,b可以比較大,最後也需要迴圈結束才計算出結果,如果a不是1,迴圈次數就大大減少
可以分情況討論 a=1和a!=1
下面給出3種方法
1 迴圈特判
#include<bits/stdc++.h>
using namespace std;
const int N=1e9;//允許的最大值 超出輸出-1
int a,b;//輸入a b
long long m=1;//儲存 a^b
int main(){
cin>>a>>b;//輸入a b
if(a==1){
cout<<"1";
return 0;
}
for(int i=0;i<b;i++){//迴圈b次
m=m*a;//m從1開始每次乘以a
if(m>N){//如果大於允許的最大值 輸出-1
cout<<"-1";
return 0;//退出程式
}
}
cout<<m;//輸出 a^b
return 0;
}
2 用快速冪解法
如下用快速冪改造後的程式,不在超時,可以順利透過
#include <bits/stdc++.h>
using namespace std;
const int N=1e9;
long long a,b,ans=1;
long long quickpow(long long a, long long b) {
while (b) {
if (b & 1) {
ans = ans * a;
}
if(a>N) return -1;
if (ans > N) return -1;
a *= a;
b >>= 1;
}
return ans;
}
int main() {
cin >> a >> b;
cout << quickpow(a, b) << endl;
return 0;
}
/*
輸入
1 992465817
輸出
1
*/
普及組第1題用快速冪有點過分了,看看還有沒有其他解法
3 pow函式解法
#include<bits/stdc++.h>
using namespace std;
const int N=1e9;//允許的最大值 超出輸出-1
int a,b;//輸入a b
double ans;
int main(){
cin>>a>>b;//輸入a b
ans=pow(a,b);
if(ans>N){
cout<<-1<<endl;
}else{
cout<<(int)ans;//輸出 a^b
}
return 0;
}
/*
輸入
1 992465817
輸出
1
*/
可以順利透過
這裡順便說一些pow函式
C++中有自帶的pow()函式,具有求指定底數的指定冪值。通常使用該函式求解冪
實現原理為快速冪,時間複雜度為O(logN)
#include<iostream>
#include<cmath>
using namespace std;
/*
pow函式
該函式接收兩個引數,base 為要取次方的數,exponent 為指數。返回結果為 base 的 exponent 次方
double x =pow(base,exponent);
pow=(2,3)=8
*/
int main(){
int base=2;
int exponent=3;
double x=pow(base,exponent);
cout<<x<<endl;
exponent=4;
x=pow(base,exponent);
cout<<x<<endl;
return 0;
}
/*
輸出
8
16
*/
如下為原題
[題目描述]
小文同學剛剛接觸了資訊學競賽,有一天她遇到了這樣一個題:給定正整數 a 和 b,求 a^b 的值是多少。
a^b 即 b 個 a 相乘的值,例如 2^3 即為 3 個 2 相乘,結果為 2×2×2=8
“簡單!”小文心想,同時很快就寫出了一份程式,可是測試時卻出現了錯誤
小文很快意識到,她的程式裡的變數都是 int
型別的。在大多數機器上,int
型別能表示的最大數為 2^31−1,因此只要計算結果超過這個數,她的程式就會出現錯誤
由於小文剛剛學會程式設計,她擔心使用 int
計算會出現問題。因此她希望你在 ab 的值超過 10^9 時,輸出一個 -1
進行警示,否則就輸出正確的 a^b 的值
然而小文還是不知道怎麼實現這份程式,因此她想請你幫忙
[輸入格式]
輸入共一行,兩個正整數 a,b
[輸出格式]
輸出共一行,如果 a^b 的值不超過 10^9,則輸出 a^b 的值,否則輸出 -1
[輸入輸出樣例]
輸入 #1
10 9
輸出 #1
1000000000
輸入 #2
23333 66666
輸出 #2
-1
說明/提示
資料規模
對於 10% 的資料,保證 b=1。
對於 30%的資料,保證 b≤2。
對於 60% 的資料,保證 b≤30,a^b≤ 10^18。
對於 100% 的資料,保證 1≤a,b≤10^9。