Given N and M, task is to find whether numbers 1 to N can be divided into two sets such that the absolute difference between the sum of two sets is M and gcd of the sum of two sets is 1 (i.e. Sum of both sets are co-prime).
Prerequisite : GCD in CPP | GCD
Examples :
Input : N = 5 and M = 7
Output : YES
Explanation : as numbers from 1 to 5 can be divided into two sets {1, 2, 3, 5} and {4} such that absolute difference between the sum of both sets is 11 – 4 = 7 which is equal to M and also GCD(11, 4) = 1.
Input : N = 6 and M = 3
Output : NO
Explanation : In this case, Numbers from 1 to 6 can be divided into two sets {1, 2, 4, 5} and {3, 6} such that absolute difference between their sum is 12 – 9 = 3. But, since 12 and 9 are not co-prime as GCD(12, 9) = 3, the answer is ‘NO’.
Approach : Since we have 1 to N numbers, we know that the sum of all the numbers is N * (N + 1) / 2. Let S1 and S2 be two sets such that,
1) sum(S1) + sum(S2) = N * (N + 1) / 2
2) sum(S1) – sum(S2) = M
Solving these two equations will give us the sum of both the sets. If sum(S1) and sum(S2) are integers and they are co-prime (their GCD is 1), then there exists a way to split the numbers into two sets. Otherwise, there is no way to split these N numbers.
Below is the implementation of the solution described above.
/* CPP code to determine whether numbers 1 to N can be divided into two sets
such that absolute difference between
sum of these two sets is M and these
two sum are co-prime*/
#include <bits/stdc++.h> using namespace std;
// function that returns boolean value // on the basis of whether it is possible // to divide 1 to N numbers into two sets // that satisfy given conditions. bool isSplittable( int n, int m)
{ // initializing total sum of 1
// to n numbers
int total_sum = (n * (n + 1)) / 2;
// since (1) total_sum = sum_s1 + sum_s2
// and (2) m = sum_s1 - sum_s2
// assuming sum_s1 > sum_s2.
// solving these 2 equations to get
// sum_s1 and sum_s2
int sum_s1 = (total_sum + m) / 2;
// total_sum = sum_s1 + sum_s2
// and therefore
int sum_s2 = total_sum - sum_s1;
// if total sum is less than the absolute
// difference then there is no way we
// can split n numbers into two sets
// so return false
if (total_sum < m)
return false ;
// check if these two sums are
// integers and they add up to
// total sum and also if their
// absolute difference is m.
if (sum_s1 + sum_s2 == total_sum &&
sum_s1 - sum_s2 == m)
// Now if two sum are co-prime
// then return true, else return false.
return (__gcd(sum_s1, sum_s2) == 1);
// if two sums don't add up to total
// sum or if their absolute difference
// is not m, then there is no way to
// split n numbers, hence return false
return false ;
} // Driver code int main()
{ int n = 5, m = 7;
// function call to determine answer
if (isSplittable(n, m))
cout << "Yes" ;
else
cout << "No" ;
return 0;
} |
/* Java code to determine whether numbers 1 to N can be divided into two sets such that absolute difference between sum of these two sets is M and these two sum are co-prime*/ class GFG
{ static int GCD ( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
// function that returns boolean value
// on the basis of whether it is possible
// to divide 1 to N numbers into two sets
// that satisfy given conditions.
static boolean isSplittable( int n, int m)
{
// initializing total sum of 1
// to n numbers
int total_sum = (n * (n + 1 )) / 2 ;
// since (1) total_sum = sum_s1 + sum_s2
// and (2) m = sum_s1 - sum_s2
// assuming sum_s1 > sum_s2.
// solving these 2 equations to get
// sum_s1 and sum_s2
int sum_s1 = (total_sum + m) / 2 ;
// total_sum = sum_s1 + sum_s2
// and therefore
int sum_s2 = total_sum - sum_s1;
// if total sum is less than the absolute
// difference then there is no way we
// can split n numbers into two sets
// so return false
if (total_sum < m)
return false ;
// check if these two sums are
// integers and they add up to
// total sum and also if their
// absolute difference is m.
if (sum_s1 + sum_s2 == total_sum &&
sum_s1 - sum_s2 == m)
// Now if two sum are co-prime
// then return true, else return false.
return (GCD(sum_s1, sum_s2) == 1 );
// if two sums don't add up to total
// sum or if their absolute difference
// is not m, then there is no way to
// split n numbers, hence return false
return false ;
}
// Driver Code
public static void main(String args[])
{
int n = 5 , m = 7 ;
// function call to determine answer
if (isSplittable(n, m))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
} // This code is contributed by Sam007 |
Yes
Time Complexity : O(log(n))
Auxiliary Space: O(1)
Please suggest if someone has a better solution which is more efficient in terms of space and time.