大概题意:一个数去分解质因数,质因数有重复的直接时no,否则是yes
刚开始de思路是改进了一下分解质因数的模板,a[i]>1直接返回false。但是题上数据范围太大,提交之后tle。
后来去嫖网上的思路,大部分是直接给代码思路,没有给一个逻辑过程,想了一会才想出来,所以准备自己写一个逻辑推导过程。
逻辑过程:
1.因为我们要判断的是质因数一旦为平方或以上之后就要判断为no,所以10^9是一个分界点(10^9^2==10^18);
2.因为大于10^6的数的立方大于10^18,所以10^6是一个分界点,目的是卡住平方小于而立方大于10^18的数。
3.所以在小于10^6的数字之中,挨个排查每个素数,然后再把剩下的n进行一个开方,若答案为整数为no,否则为yes,(n==1,则为yes);
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#define ll long long
#define in(x) scanf("%d",&x)
#define in64(x) scanf("%lld",&x)
#define debug(x) cerr<<#x<<" : "<<x<<endl
#define put(x,s) printf("Case %d: %s\n",x,s)
using namespace std;
bool vis[1000010];
int prime[1000000];
int findall(int n=1000000){
memset(vis,0,sizeof(vis));
for(int i=2;i*i<=n;i++){
if(!vis[i]){
for(int j=i*i;j<=n;j+=i){
vis[j]=1;
}
}
}
int k=0;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[k++]=i;
}
}
return k;
}
int main(){
int t;in(t);
ll k=findall();
int c=0;
while(t--){
c++;
ll n;in64(n);
int cnt;
for(ll i=0;i<k;i++){
cnt=0;
while(n%prime[i]==0){
cnt++;
n/=prime[i];
}
if(cnt>1){
break;
}
}
if(cnt>1){
//no
put(c,"No");
}
else{
if(n==1){
//yes
put(c,"Yes");
}
else{
long double tmp=sqrt(n);
if(floor(tmp)==tmp){
//no
put(c,"No");
}
else{
put(c,"Yes");
//yes
}
}
}
}
return 0;
}