从数学原理出发:
数字N可表示为2个平方的和,当且仅当在N的素数因子分解中,
(4k+3)
形式的每个素数都出现偶数次!
我所做的是预先计算所有4k+3
个数字,并通过连续分割来检查它的频率。
该程序是根据约束编写的:
1 < T <100
0 < N < 10 ^ 12
import java.util.Scanner;
public class TwoSquaresOrNot {
static int max = 250000;
static long[] nums = new long[max];
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 0; i < max; ++i)
nums[i] = 4 * i + 3;
while (T-- > 0) {
long n = sc.nextLong();
System.out.println((canWrite(n) ? "Yes" : "No"));
}
}
private static boolean canWrite(long n) {
// TODO Auto-generated method stub
for (int i = 0; i < nums.length; ++i) {//loop through all the numbers
if (nums[i] > n)
return true;
int count = 0;
while (n % nums[i] == 0) {
count++;
n /= nums[i];
}
if (count % 2 != 0)//check for odd frequency
return false;
}
return true;
}
}
但这似乎不适用于SPOJ网站。
我错过了什么吗?或者我做错了什么?
0
也在此考虑。
Some valid cases are:
1 = 1^2 + 0^2
8 = 2^2 + 2^2
答案 0 :(得分:2)
根据OP的评论编辑。
夫妻俩。首先:如果您正在寻找素数分解,那么当您在&gt;时可以停止。 sqrt(n),你不必一直走到n。
所以你的代码应该像:
private static boolean canWrite(long n) {
// TODO Auto-generated method stub
for (int i = 0; i < nums.length; ++i) {//loop through all the numbers
//FIRST CHANGE: Sqrt
if (nums[i] > Math.sqrt(n))
break;
int count = 0;
while (n % nums[i] == 0) {
//SECOND CHANGE: count as an array
count[i]++;
n /= nums[i];
}
}
//SECOND CHANGE: count as an array
for (int i=0; i<count.length; i++) {
if (count[i] %2 != 0) return false;
}
return true;
}