Square Number
Problem Description
In mathematics, a square number is an integer that is the square of an integer. In other words, it is the product of some integer with itself. For example, 9 is a square number, since it can be written as 3 * 3.
Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a square number.
Input
The first line of the input contains an integer T (1 ≤ T ≤ 20) which means the number of test cases.
Then T lines follow, each line starts with a number N (1 ≤ N ≤ 100000), then N integers followed (all the integers are between 1 and 1000000).
Output
For each test case, you should output the answer of each case.
Example Input
1 5 1 2 3 4 12
Example Output
2
题意:
给出n个数,算出有多少对数,两两相乘为平方数。
分析:
一个数为偶数,那么它的每个质因子个数肯定也是偶数个。现在的问题就是,如果有一个数p,把它的个数为偶数的质因子去掉之后就剩下了个数为奇数的质因子,对数q做同样的操作,那么p与q必须有相同的质因子,且每个质因子个数和为偶数。
具体的做法就是把1000000以内,所有质数的平方都筛选出来,然后将读入的数对质数的平方进行取模,模出来的结果肯定就是所有个数为1的质因子的乘积,对相应的乘积做好记录,每个读入的数都进行这样操作,就可以与前面记录过的配对。具体实现请看代码。
总结:
对于这道题,一开始想到的还是存每个数的质因子,然后进行用map、set搞搞,还是
想不到更高效的办法。硬伤.....
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 1e6+10;
int prim[1005], it[1005], vis[maxn];
int amount = 0;
void init()
{
for(int i = 2; i <= 1000; i++)//筛选素数
if(prim[i] == 0)
for(int j = i*i; j <= 1000; j += i)
prim[j] = 1;
int cou = 0;
for(int i = 2; i <= 1000; i++)//素数平方打表
if(prim[i] == 0)
it[amount++] = i * i;
}
int main()
{
int n, ans, t, T;
init();
cin >> T;
while(T--)
{
ans = 0;
cin >> n;
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++)
{
cin >> t;
for(int j = 0; j < amount; j++)
if(t % it[j] == 0)
while(t % it[j] == 0)
t /= it[j];
ans += vis[t];//统计状态
vis[t]++;
}
cout << ans << endl;
}
return 0;
}