题意:给你若干个数,找两两相乘是立方数的个数。
思路:一个数肯定能分解成若干个素数相乘,那么我们就可以除以这些素数的立方,然后再找到能够跟这个数一起组成立方数即可。
代码;
#include<bits/stdc++.h>
using namespace std;
int dp[1005];
int pri[1005];
int num;
int k[1000005];
void prime()
{
num=0;
memset(pri,0,sizeof(pri));
for(int i=2;i<=1000;i++)
{
if(!pri[i])dp[num++]=i;
for(int j=i+i;j<=1000;j+=i)
{
if(!pri[j])
{
pri[j]=1;
}
}
}
}
int main()
{
prime();
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
memset(k,0,sizeof(k));
int ans=0;
for(int i=0;i<n;i++)
{
int x;
int flag=1;
long long int t=1;
long long int p=1;
scanf("%d",&x);
for(int j=0;j<num&&dp[j]<=x;j++)
{
long long y=dp[j]*dp[j]*dp[j];
while(x%y==0)x/=y;
if(x%(dp[j]*dp[j])==0)
{
x/=(dp[j]*dp[j]);
t=t*dp[j]*dp[j];
if(flag) p*=dp[j];
}
else if(x%dp[j]==0)
{
x/=dp[j];
t=t*dp[j];
if(flag) p*=(dp[j]*dp[j]);
}
if(p>1000000)flag=0;
}
if(flag)
{
if(x!=1)p=p*x*x;
if(p<=1000000)ans+=k[p];
}
if(x!=1)t*=x;
k[t]++;
}
printf("%d\n",ans);
}
return 0;
}