solution1(通过10%)
#include<stdio.h>
#include<math.h>
typedef long long LL;
int isPrime(LL n){
LL sqr = (int)sqrt(1.0 * n);
for(int i = 2; i <= sqr; i++){
if(n % i == 0) return 0;
}
return 1;
}
int main(){
int t;
LL a;
scanf("%d", &t);
while(t--){
LL f[100] = {0}, sqr, num = 0, odd = 0, even = 0, flag = 0;
scanf("%lld", &a);
if(isPrime(a)) flag = 1;
else{
sqr = (int)sqrt(1.0*a);
for(int i = 2; i <= sqr; i++){
if(a % i == 0){
while(a % i == 0){
a /= i;
f[num]++;
}
if(f[num] == 1) {
flag = 1;
break;
}
else if(f[num] % 2 == 0) even++;
else odd++;
num++;
}
if(odd > 2 || (odd == 2 && even > 0)){
flag = 1;
break;
}
}
if(a > 1) flag = 1;
}
if(flag) printf("no\n");
else printf("yes\n");
}
return 0;
}
solution2
1 <= ai <= 1018,
奇数次幂可以分解为偶数次幂*奇数次幂
则能够拆分的数最后一定能分解为下列形式:
- a2*b3
==》至多有五次方,而上界1018开五次方大约是4000左右
#include<stdio.h>
#include<math.h>
int main(){
printf("%lld", (long long)pow(1e18, 0.2));//3981
return 0;
}
列出4000以内的素数,看是否有只出现一次的质因数,若有则一定不能拆分,木有人和它配对不满足指数大于等于2
分解后a等于1或者是大于4000的因子,这样一番分解后a不会太大了,直接判断是否能够分解为平方或者立方的形式融入其中即可
#include<stdio.h>
#include<math.h>
typedef long long LL;
LL p[4005] = {0}, prime[4005], n = 0;
int check(LL a){
LL s, num;
for(int i = 1; i <= n && prime[i] * prime[i] <= a; i++){
num = 0;
if(a % prime[i] == 0){
while(a % prime[i] == 0){
a /= prime[i];
num++;
}
if(num == 1) return 0;
}
}
s = sqrt(1.0 * a);
while(s*s <= a){
if(s*s == a) return 1;
s++;
}
s = pow(a, 1.0 * 1 / 3);
while(s*s*s <= a){
if(s*s*s == a) return 1;
s++;
}
return 0;
}
int main(){
int t;
LL a;
scanf("%d", &t);
for(int i = 2; i <= 4000; i++){
if(!p[i]){
prime[++n] = i;
for(int j = i * i; j <= 4000; j += i){
p[j] = 1;
}
}
}
while(t--){
scanf("%lld", &a);
if(check(a)) printf("yes\n");
else printf("no\n");
}
return 0;
}