Number which can be written as sum of two Squares
Asked Answered
S

1

6

From the math principle:

A number N is expressible as a sum of 2 squares if and only if in the prime factorization of N, every prime of the form (4k+3) occurs an even number of times!

What I did is pre-calculated all the 4k+3 numbers and checking it's frequency by continuous division.

This program is written in correspondence to the constraints:

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;
    }
}

But this doesn't seem to work in the SPOJ website.

Am I missing something? Or am I doing something wrong?

0 is also considered in this.

Some valid cases are:

1 = 1^2 + 0^2
8 = 2^2 + 2^2
Slowworm answered 28/8, 2015 at 11:47 Comment(5)
I didn't test your code but you can try to remove the intermediate System.out.print. It might influence the website.Bernal
Ahhhh! thanks. I didn't see that. Wrong answer even though.Slowworm
Does "0" count as a square? If not, 9 is a trivial counterexample.Pyromagnetic
Yes it does count as a sum of square number. 0^2 + 3^2 = 9 is valid.Slowworm
Hi OP. If I understood the theorem statement correctly, there are a couple issues with your code that I highlighted below. Let me know if that's correct.Sac
S
2

EDITED AS PER COMMENTS OF OP.

Couple things. First: if you are looking for the prime factorization, you can stop when you are at > sqrt(n), you don't have to go all the way to n.

So your code should become something like:

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;
}
Sac answered 28/8, 2015 at 12:45 Comment(2)
I really appreciate the square-root n approach. Although it was not timing out for this approach. I'll consider that as well. Second thing checking for isPrime() is a waste of time. If it isn't a prime it won't have multiples as the previous primes remove these(3 and 5 remove 15 multiples). It just is a bit overhead. The third thing, You got the statement in the wrong way. It states that even if one of the numbers which can be written as 4k+3 has odd frequency, then it cannot be represented as a sum of 2 squares. Thank you.Slowworm
Checking primarily for 250000 huge numbers isn't a good idea. As its factors will be eliminated by the earlier primes. Thus the control won't get into the while loop. The rest is self explainableSlowworm

© 2022 - 2024 — McMap. All rights reserved.