Square Pair(一对二次幂)
时间限制:2s 内存限制:1024MB
【原题地址】
所有图片源自Atcoder,题目译文源自脚本Atcoder Better!
【问题描述】
【输入格式】
【输出格式】
【样例1】
【样例输入1】
5
0 3 2 8 12
【样例输出1】
6
【样例说明1】
【样例2】
【样例输入2】
8
2 2 4 6 3 100 100 25
【样例输出2】
7
【解题思路】
老汉使用到的是贪心的解题方式
该题是求一个整数序列存在几对平方数组合。
单纯的判断每个组合的乘积是否为平方数,很显然组合以及判断的过程,在两秒的时间内是无法完成的,那么我们运用到贪心思想,去转换这个求值过程,我们发现一个较大的平方数可以分为几个小的平方数,我们只需要去求出它组成平方数所缺少的那个值,以及在这个数之前出现过几个同样缺少这个值的数,与之成对,即为平方数组合。
代码注释有详细过程
【代码】
package ABC342_D_SquarePair;
import java.io.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
static StreamTokenizer st = new StreamTokenizer(br);
public static int readInt() throws IOException {
st.nextToken();
return (int) st.nval;
}
public static void main(String[] args) throws IOException {
int n = readInt();
long ans = 0;
// 存放有几个缺少下标位所表示的值就能凑出平方数的个数
long[] pow = new long[(int) 2e5 + 1];
for (int i = 0; i < n; i++) {
int a = readInt();
// 最小平方数起始为2*2
int pw = 2;
while ((pw * pw) <= a) {
while (a % (pw * pw) == 0) {
a /= (pw * pw);
}
// 不断增加,寻找a所包含的最小平方数(除1外)
pw++;
}
// 最终求出的a为组成平方数缺少的那个值,当前数答案为之前出现过几个同样缺少该值的数
ans += pow[a];
// 缺少a值的数加一(当前数)
pow[a]++;
}
// 0乘以任何数都为平方数
ans += pow[0] * (n - pow[0]);
pw.println(ans);
pw.flush();
pw.close();
br.close();
}
}