题意:给你一个数,判断其中是否有平方因子。
解题思路:因为题目给我们的数n的范围为:[2,10^18],直接用暴力是无法做的。所以我们先对有平方因子的数进行分析,一个数有平方因子,那么它一定有素数平方因子;
设:
n=p1^e1*p2^e2*p3^e3*…pk^ek。(其中p1···pk为素因子),如果e1~ek中有任何一个数为2,则说明X必定有素因子的平方,如果x是两个素因子的乘积,我们就可以直接
这么做:x=sqrt(n),再判断x的平方是不是等于n,来判断n是否有平方因子。如果x当中包括了多个素因子的乘积,那么由三个最大的素因子,这个素因子最大为多大呢
1000000*1000000*10000000=10^18;所以我们只要找出1000000以内的素数,然后在这里找是否有素因子平方。大于这个范围的话,我们就可以认为这个数n最多可能由两个素数成绩组成的,然后用前面那种方法判断是否有平方因子。
代码:
#include<iostream>
#include<cmath>
using namespace std;
const int N=1000001;
bool is[N];
int prm[78500];
int getprm(int n)
{
int i,j,k=0;
int s,e=(int)(sqrt(0.0+n)+1);
memset(is,1,sizeof(is));
prm[k++]=2;
is[0]=is[1]=0;
for(i=4;i<n;i+=2)is[i]=0;
for(i=3;i<e;i+=2)
{
if(is[i])
{
prm[k++]=i;
for(s=i*2,j=i*i;j<n;j+=s)
{
is[j]=0;
}
}
}
for(;i<n;i+=2)if(is[i])prm[k++]=i;
return k;
}
int main()
{
int i,t,ans=0;
__int64 n;
double x;
int k=getprm(1000000);
//printf("%d",prm[k-1]);
scanf("%d",&t);
while(t--)
{
scanf("%I64d",&n);
ans++;
bool flag=0;
for(i=0;i<k&&n>=(__int64)prm[i]*prm[i];i++)
{
if(n%((__int64)prm[i]*prm[i])==0)
{
flag=1;
break;
}
while(n%prm[i]==0)n/=prm[i];
}
x=sqrt(n+0.0);
//printf("%I64d %lf\n",n,x);
if((__int64)x*(__int64)x==n)flag=1;
if(flag)
printf("Case %d: No\n",ans);
else printf("Case %d: Yes\n",ans);
}
return 0;
}