题目:http://acm.hdu.edu.cn/showproblem.php?pid=6216
题意:给出一个素数p,判断它是不是两个数的立方差。
分析:
法一:由立方差公式可知a^3-b^3=(a-b)(a^2+ab+b^2),由于p为素数所以只能是p=1*p;容易得a-b=1,a^2+ab+b^2=p;解方程可得a=(3+sqrt(12p-3))/6;只需判断sqrt(12p-3)、a是否为整数就行了。
法二:由立方差公式解得b(b+1)=(p-1)/3;令b=sqrt((p-1)/3);再判断b(b+1)和(p-1)/3是不是相等就行了。
法三:由法一可知a^3-b^3=a^2+ab+b^2,p=3b^2+3b+1,而p<=10^12,所以估算a一定小于10^6,枚举b的值,并用数组保存结果,每次判断p是不是在数组中。
代码:
///法一
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int t;
long long p;
cin>>t;
while(t--){
cin>>p;
double num1=sqrt(12*p-3);
long num2=num1;
if((double)num2==num1){
long num3=num1;
if((3+num3)%6==0){
cout<<"YES"<<endl;
continue;
}
}
cout<<"NO"<<endl;
}
}
///法二
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int t;
long long p;
cin>>t;
while(t--){
cin>>p;
long long t=(long long)sqrt((p-1)/3.0);
if(3*t*(t+1)+1==p) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
///法三
#include<iostream>
using namespace std;
const int maxn = 1e6;
long long a[maxn];
int main(){
for(long long i=1;i<maxn;i++)
a[i]=3*i*i+3*i+1;
int t;
long long p;
cin>>t;
while(t--){
cin>>p;
int flag=0;
for(int i=1;i<=maxn;i++){
if(a[i]==p){
flag=1;
break;
}
else if(a[i]>p)
break;
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
总结:本来是一道水题,还是错了几遍,p<=10^12,一开始用的long,以为足够了,后来看书发现现在int居然和long的范围是一样的(坑啊!)最大也只有2^31,必须要用long long!!!