Open In App

Check if there exists two non-intersect ranges

Last Updated : 02 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two non-negative integers X and Y, the task is to output the two non-intersecting ranges of non-negative integers such that the sum of the starting and ending point of the first range is equal to X and the product of the starting and ending point of the second range is equal Y. If there is no possible answer output -1. If there are multiple possible answers, then print any of them.

Examples:

Input: X = 6, Y = 50
Output: {3, 3} {5, 10}

Explanation: First and second range is {3, 3} and {5, 10} respectively. Sum of starting and ending point of first range is 3+3 = 6, which is equal to X and product of starting and ending point of second range is 5*10 = 50, which is equal to Y. These both ranges are non-intersecting as well. Therefore, both output ranges are valid.

Input: X = 1, Y = 3
Output: -1

Explanation: It can be verified that there are no two ranges [a, b] and , such that a+b = X, c*d = Y and both ranges are non-intersect.

Approach: This problem can be solved using the Greedy approach.

Think about the following questions.

  • When do we have the least chance of overlap?
  • When we have the least length of both the possible segments.

Let’s focus on the first segment for now assume the value of X to be 10, then the possible segments can be- [0, 10], [1, 9], [2, 8], [3, 7], [4, 6] and [5, 5].

  1. If we observe these ranges, we see that the segment becomes smaller as we reach the half of X. Therefore, for the first segment to have the smallest length, there are only 2 possible ranges- [X/2, X/2] when X is even and [X/2, X/2+1] when X is odd.
  2. Moving on to the second segment. Assume the value of Y to be 24, then the possible segments can be- [1, 24], [2, 12], [3, 8] and [4, 6]. If we observe these ranges, we see that the segment becomes smaller as we reach the square root of Y. Therefore, for the second segment to have the smallest length, we will find the last factor of Y in the range [1, sqrt(Y)].
  3. If we find any overlap between the above 2 segments, then return -1 otherwise return the segments.

Steps to solve the problem:

  • Create two variables let say start1 and end1 for the first segment and initialize both of them to X/2.
  • If (X is odd), then end1++.
  • Create two variables start2 and end2 for the second segment.
  • Run a loop from i = 1 to Sqrt(Y) and follow below mentioned steps under the scope of loop:
    • If(Y % i == 0), then update start2 = i and end2 = (Y / i).
  • In case of no overlap (start1 > end2 or end1 < start2), then print the ranges, else print -1.

Below is the implementation of the above approach:

C++14




// C++ code to implement the approach:
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if there exist
// two valid ranges or not
void Check_ranges(long X, long Y)
{
    // Variables to store the first
      // segment's starting and
    // ending point
    long start1 = X / 2;
    long end1 = X / 2;
    if (X & 1) {
        end1++;
    }
 
    // Variables to store the second
      // segment's starting and
    // ending point
    long start2 = 0, end2 = 0;
    for (long i = 1; i * i <= Y; i++) {
        if (Y % i == 0) {
            start2 = i;
            end2 = Y / i;
        }
    }
 
    // Checking if there are non-intersecting
      // ranges or not
    if (start1 > end2 || end1 < start2) {
        cout << start1 << " " << end1 << endl;
        cout << start2 << " " << end2 << endl;
    }
    else {
        cout << -1 << endl;
    }
}
 
// Driver Code
int main()
{
    // Inputs
    long X = 1;
    long Y = 3;
 
    // Function call
    Check_ranges(X, Y);
 
    return 0;
}


Java




// Java code to implement the approach:
 
public class GFG {
    // Driver Function
    public static void main(String[] args)
    {
        // Inputs
        long X = 1;
        long Y = 3;
 
        // function call
        Check_ranges(X, Y);
    }
 
    // Method to check if there exists two
    // valid ranges or not
    public static void Check_ranges(long X, long Y)
    {
        // Variables to store
        // First Segment's starting and
        // ending point
        long start1 = X / 2;
        long end1 = X / 2;
        if ((X & 1) == 1) {
            end1++;
        }
 
        // Variables to store
        // First Segment's starting
        // and ending point
        long start2 = 0, end2 = 0;
        for (long i = 1; i * i <= Y; i++) {
            if (Y % i == 0) {
                start2 = i;
                end2 = Y / i;
            }
        }
 
        // Checking if there are non
        // intersecting or not
        if (start1 > end2 || end1 < start2) {
            System.out.println(start1 + " " + end1);
            System.out.println(start2 + " " + end2);
        }
        else {
            System.out.println(-1);
        }
    }
}


Python3




# Python code to implement the approach:
 
# Function to check if there exist two
# valid ranges or not
def check_ranges(X, Y):
    # Variables to store the first segment's
    # starting and ending point
    start1 = X // 2
    end1 = X // 2
    if X % 2:
        end1 += 1
 
    # Variables to store the second segment's
    # starting and ending point
    start2 = 0
    end2 = 0
    for i in range(1, int(Y ** 0.5) + 1):
        if Y % i == 0:
            start2 = i
            end2 = Y // i
 
    # Checking if there are non-intersecting
    # ranges or not
    if start1 > end2 or end1 < start2:
        print(start1, end1)
        print(start2, end2)
    else:
        print(-1)
 
# Driver code
X = 1
Y = 3
 
# Function call
check_ranges(X, Y)


C#




// C# Implementation:
using System;
 
public class Program
{
    public static void Main(string[] args)
    {
        // Inputs
        long X = 1;
        long Y = 3;
 
        // Function call
        CheckRanges(X, Y);
    }
 
    // Method to check if there exists two valid ranges or not
    public static void CheckRanges(long X, long Y)
    {
        // Variables to store First Segment's starting and ending point
        long start1 = X / 2;
        long end1 = X / 2;
        if ((X & 1) == 1)
        {
            end1++;
        }
 
        // Variables to store First Segment's starting and ending point
        long start2 = 0, end2 = 0;
        for (long i = 1; i * i <= Y; i++)
        {
            if (Y % i == 0)
            {
                start2 = i;
                end2 = Y / i;
            }
        }
 
        // Checking if there are non intersecting or not
        if (start1 > end2 || end1 < start2)
        {
            Console.WriteLine(start1 + " " + end1);
            Console.WriteLine(start2 + " " + end2);
        }
        else
        {
            Console.WriteLine(-1);
        }
    }
}
 
// This code is contributed by Tapesh(tapeshdua420)


Javascript




// JavaScript code for the above approach
 
function checkRanges(X, Y) {
    // Variables to store the first segment's starting and ending point
    let start1 = Math.floor(X / 2);
    let end1 = Math.floor(X / 2);
    if (X % 2 !== 0) {
        end1++;
    }
 
    // Variables to store the second segment's starting and ending point
    let start2 = 0;
    let end2 = 0;
    for (let i = 1; i * i <= Y; i++) {
        if (Y % i === 0) {
            start2 = i;
            end2 = Y / i;
        }
    }
 
    // Checking if there are non-intersecting ranges or not
    if (start1 > end2 || end1 < start2) {
        console.log(start1, end1);
        console.log(start2, end2);
    } else {
        console.log(-1);
    }
}
 
// Driver Code
const X = 1;
const Y = 3;
 
// Function call
checkRanges(X, Y);
 
// This code is contributed by Abhinav Mahajan (abhinav_m22)


Output

-1







Time Complexity: O(Sqrt(Y))
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads