乘方
题目来源
CSP2022-J-T1:http://oj.tfls.net/d/lnzt/p/13
题目分析
根据【数据范围】来分析
题解
int
占用空间4字节,32位
,取值范围-2^31 ~ 2^31-1
,大约能够表示绝对值不超过2.1*10^9
的整数
long long
占用空间8字节,64位
,取值范围-2^63 ~ 2^63-1
,大约能够表示绝对值不超过9.2*10^18
的整数
-1分
cout<<-1;//多少分代表出题人的良心指数
对于 10% 的数据,保证 b = 1。
long long a, b;
cin>>a>>b;//a^b=1
cout<<a;
对于 30% 的数据,保证 b ≤ 2。
int a, b;
long long ans;
cin>>a>>b;
ans=(long long)a*a;//注意此处要强制将a转换为long long
if(ans >= int(1e9)) //1e9表示的10^9
cout<<-1;
else
cout<<ans;
对于 60% 的数据,保证 b ≤ 30,ab ≤ 1018。
- 解法1
int a, b;
long long ans=1;//初始值为1
cin>>a>>b;
for(int i=1; i<=b; i++)
ans=ans*a; //此处ans和a必须有一个为long long
if(ans >= int(1e9)) //1e9表示的10^9
cout<<-1;
else
cout<<ans;
- 解法2
double
占用空间8字节,64位
,取值范围大约指数绝对值不超过307,15位有效数字
int a, b;
long long ans=1;
cin>>a>>b;
ans=pow(a, b);//pow的返回值类型是double,注意此处发生类型转换,可以用pow(10,18)来测试
if(ans >= int(1e9)) //1e9表示的10^9
cout<<-1;
else
cout<<ans;
对于 100% 的数据,保证 1 ≤ a, b ≤ 109。
如按照上面解法2,必然会有部分分超时,因为我们一般认为程序运行1e8就会超时,所以不能纯暴力模拟
- 解法1:先求出a^n=1e9时n的值,即log(a,1e9)=n,比较n和b的值即可,前提基础知识是会使用log函数
int a, b;
int max_ab=1e9;// 定义超范围值
cin>>a>>b;
int n=floor(log(max_ab)/log(a));//a^n=max_ab的逆运算,求n向下取整
int ans=-1;//如果b>=n输出答案为-1
if(b <= n)
ans=pow(a, b);
cout<<ans;
- 解法2:快速幂,求出a^b的值
#include<bits/stdc++.h>
using namespace std;
bool f;//标记a^b是否超出 1e9
long long qsm(int a, int b){//时间复杂度为log(b)
if(b==0)
return 1;
long long aa=qsm(a, b/2);
long long ret=aa*aa;
if(b&1)
ret=ret*a;
if(ret >= 1e9 || ret<0)//可能会数据溢出
f=1;
return ret;
}
int main()
{
int a, b, ans;
int max_ab=1e9;// 定义超范围值
cin>>a>>b;
long long ab=qsm(a, b);//通过快速幂来求a^b的值,并求出f
if(!f)
ans=ab;
else
ans=-1;
cout<<ans;
return 0;
}
- 解法3:倍增
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a, b, ans=0;
int max_ab=1e9;// 定义超范围值
cin>>a>>b;
long long ab=1;//用于计算a^b
long long aa=a;//用于计算a的幂次
while(b){//时间复杂度为log(b)次
if(b&1)
ab=ab*aa;
if(ab>=max_ab || ab<0){
ans=-1;
break;
}
aa=aa*aa;
b>>=1;//b往右1位
}
if(ans==0)
ans=ab;
cout<<ans;
return 0;
}