您的位置:首页 > 其它

sdut 3258 (第六届山东省ACM省赛H题)

2017-04-30 17:04 381 查看
题意:

一个数可以表示为另一个数的平方叫做square number,像3*3 = 9,9是一个square number。

给定n个数,求有多少对(ai,bi)满足ai×bi为一个square number,其中i != j。

思路:

除1之外的任何一个整数都可分解为有限个质数的乘积,所以可以推得两个数分解为质因数乘积之后的乘积,只有满足任意一个质因数的个数为偶数个时,它们的乘积才为一个square number,简单来讲就是平方数可以表示为若干个偶次幂的质数的乘积。所以对于一个数的质因数,有偶数个,则忽略,奇数个,就表明仍需要一个此质数,最后把所有的仍需要的质数的乘积记作now记录到一个facade数组里,并ans
+= 之前的facade[now]即可。

但,还不够,仍需要一个优化,看代码。

#include <algorithm>
#include <iostream>
#include <string.h>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std;
const int maxn = 1000000;
int prime[maxn+5]; //素数筛选
int facade[maxn+5]; //记录之前的now有多少个
int main(){
memset(prime, 0, sizeof prime);
for(int i = 2; i <= sqrt(maxn); ++i){
if(!prime[i])
for(int j = i*i; j <= maxn; j+=i) prime[j] = 1;
}
int n, t, k, ct, now;
scanf("%d", &t);
while(t--){
memset(facade, 0, sizeof facade);
scanf("%d", &n);
LL ans = 0;
for(int i = 1; i <= n; ++i){
scanf("%d", &k);
now = 1;
for(int j = 2; j <= maxn; ++j){ //分解质因数
if(prime[j]) continue;
ct = 0;
while(k%j == 0){
++ct;
k /= j;
}
if(ct%2 == 1) now *= j; //质因数个数为奇数时,now *= j;
if(k == 1 || !prime[k]){ //此处需要优化,如果k有一个很大的质因数,
now *= k; //那么内层的循环耗时也是相当严重的
break; //所以优化这儿判断即可
}
}
ans += facade[now];
++facade[now];
}
printf("%lld\n", ans); //ans > int
}
return 0;
}

继续加油~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: