题目描述
ADA Ⅱ型数是指能表达成p^2与q^3两者之乘积的整数,p和q均大于1且不相等。72=2^3*3^2, 是最小的ADA Ⅱ型数。给定一个整数n,判定其是否为ADA Ⅱ型数。
ADA Ⅱ型数是指能表达成p^2与q^3两者之乘积的整数,p和q均大于1且不相等。72=2^3*3^2, 是最小的ADA Ⅱ型数。给定一个整数n,判定其是否为ADA Ⅱ型数。
输入
少于4000行数据组成,每行一个整数n(0<n<2^31)。
输出
每个整数n对应一行输出,如果是ADA Ⅱ型数,则输出一行YES,否则输出一行NO。
少于4000行数据组成,每行一个整数n(0<n<2^31)。
输出
每个整数n对应一行输出,如果是ADA Ⅱ型数,则输出一行YES,否则输出一行NO。
样例输入
1
72
样例输出
NO
YES
提示
1
72
样例输出
NO
YES
提示
方法一
对于已经确定的幂次的表达式很好求,划出边界值,然后试数。
试数有两种方法,q或p,这里选q,因为n/q^3划的p范围小一些,算法效率相对高。
n最大是2^31,当p最小是2,n最大是2^31,则p^2=2^2,则p^2=2^31/2^2=2^29,则q最大取到2^10^(29/3)=812.7。
所以确定了q的范围为2~816(只要大于等于813即可)
然后循环每次q,去反求p,看p是否满足条件。
参考源码
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "iostream"
#include "cmath"
using namespace std;
int main()
{
long long n,i,a,b,rest,ans;
while(~scanf("%lld",&n))
{
int flag=0;
for(i=2;i<=816;i++)
{//n最大为2147483648;a最小为8,即最大rest=536870912;最大b=23170
a=i*i*i;
if(a>=n){
break;
}
if(n%a){//判断是否整除
continue;
}
rest=n/a;
double f=sqrt(rest);
b=sqrt(rest);
if(f==b && b!=i){
flag=1;
break;
}
}
if(flag==1){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
方法二是调用C++中的STL,利用容器set实现。
代码如下:
#include <set>
#include <cstdio>
#include <climits>
using namespace std;
set<int> ada;
int main()
{
int i, j, n;
for(i=2;i*i<=INT_MAX/i;i++)
for(j = 2; j * j <= INT_MAX / (i * i * i); j++)
if(j != i)
ada.insert(i * i * i * j * j);
while(~scanf("%d", &n)){
if(ada.find(n) == ada.end())
puts("NO");
else
puts("YES");
}
return 0;
}
练习平台
http://acm.hnust.cn/JudgeOnline/problem.php?id=1547