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

28 篇文章 0 订阅
19 篇文章 2 订阅

题意:

一个数可以表示为另一个数的平方叫做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;
}

继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值