Maximum times X and Y can be reduced to near 0 using numbers A or B
Last Updated :
17 Aug, 2021
Given 4 integers X, Y, A, B. In one move either decrease X by A and Y by B or decrease X by B and Y by A. Calculate maximum possible moves. Given 4 integers X, Y, A, B. In one move we can make X = X – A and Y = Y – B or X = X – B and Y = Y – A. Calculate maximum total possible moves.
Example:
Input: X = 10, Y = 12, A = 2, B = 5
Output: 3
Explanation: 1st move: X = 8, Y = 7 after subtracting X by A and Y by B
2nd move: X = 6, Y = 2 after subtracting X by A and Y by B
3rd move: X = 1, Y = 0 after subtracting X by B and Y by A
So a total of 3 moves can be performed.
Input: X = 1, Y = 1, A = 2, B = 2
Output: 0
Naive Approach: At every value of X and Y we can subtract max of A and B from max of X and Y and subtract min of A and B from min of X and Y until X and Y stays greater than zero.
Efficient Approach: Given problem can be solved using binary search on answer technique.
- The key idea here is that if for any number of moves N if it is possible to perform this many moves then we can also perform N – 1 moves.
- So we can do a binary search over the answer. Fix the range L = 1 and R = 10000000 (Change this if there are large integer values) and for each value mid = (L + R)/2 check if we can perform this much of moves. If possible then shift L = mid + 1, else R = mid – 1. Return the maximum possible value.
- To check for any number mid, we have to decrease X and Y at least mid * min(A, B) and for the remaining element, we can calculate total values for remaining for |A – B|. If these values are greater than mid then increase our right range otherwise decrease the left range.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define MAXN 10000000 // MAXN = 1e7
bool can( int Mid, int X, int Y, int A, int B)
{
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
if (p1 < 0 || p2 < 0) {
return false ;
}
int k = A - B;
if (k == 0) {
return true ;
}
int val = p1 / k + p2 / k;
if (val >= Mid) {
return true ;
}
return false ;
}
int maxPossibleMoves( int X, int Y, int A, int B)
{
int ans = 0;
int L = 1, R = MAXN;
while (L <= R) {
int Mid = (L + R) / 2;
if (can(Mid, X, Y, A, B)) {
L = Mid + 1;
ans = max(ans, Mid);
}
else {
R = Mid - 1;
}
}
return ans;
}
int main()
{
int X = 10, Y = 12, A = 2, B = 5;
if (A < B) {
swap(A, B);
}
cout << maxPossibleMoves(X, Y, A, B);
}
|
Java
import java.io.*;
class GFG{
static int MAXN = 10000000 ;
static boolean can( int Mid, int X, int Y,
int A, int B)
{
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
if (p1 < 0 || p2 < 0 )
{
return false ;
}
int k = A - B;
if (k == 0 )
{
return true ;
}
int val = p1 / k + p2 / k;
if (val >= Mid)
{
return true ;
}
return false ;
}
static int maxPossibleMoves( int X, int Y, int A, int B)
{
int ans = 0 ;
int L = 1 , R = MAXN;
while (L <= R)
{
int Mid = (L + R) / 2 ;
if (can(Mid, X, Y, A, B))
{
L = Mid + 1 ;
ans = Math.max(ans, Mid);
}
else
{
R = Mid - 1 ;
}
}
return ans;
}
public static void main(String[] args)
{
int X = 10 , Y = 12 , A = 2 , B = 5 ;
if (A < B)
{
int temp = A;
A = B;
B = temp;
}
System.out.println(maxPossibleMoves(X, Y, A, B));
}
}
|
Python3
MAXN = 10000000
def can(Mid, X, Y, A, B):
p1 = X - Mid * B
p2 = Y - Mid * B
if (p1 < 0 or p2 < 0 ):
return False
k = A - B
if (k = = 0 ):
return True
val = p1 / / k + p2 / / k
if (val > = Mid):
return True
return False
def maxPossibleMoves(X, Y, A, B):
ans = 0
L = 1
R = MAXN
while (L < = R):
Mid = (L + R) / / 2
if (can(Mid, X, Y, A, B)):
L = Mid + 1
ans = max (ans, Mid)
else :
R = Mid - 1
return ans
X = 10
Y = 12
A = 2
B = 5
if (A < B):
tmp = A
A = B
B = tmp
print (maxPossibleMoves(X, Y, A, B))
|
C#
using System;
class GFG{
static int MAXN = 10000000;
static Boolean can( int Mid, int X, int Y,
int A, int B)
{
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
if (p1 < 0 || p2 < 0)
{
return false ;
}
int k = A - B;
if (k == 0)
{
return true ;
}
int val = p1 / k + p2 / k;
if (val >= Mid)
{
return true ;
}
return false ;
}
static int maxPossibleMoves( int X, int Y, int A, int B)
{
int ans = 0;
int L = 1, R = MAXN;
while (L <= R)
{
int Mid = (L + R) / 2;
if (can(Mid, X, Y, A, B))
{
L = Mid + 1;
ans = Math.Max(ans, Mid);
}
else
{
R = Mid - 1;
}
}
return ans;
}
public static void Main(String[] args)
{
int X = 10, Y = 12, A = 2, B = 5;
if (A < B)
{
int temp = A;
A = B;
B = temp;
}
Console.Write(maxPossibleMoves(X, Y, A, B));
}
}
|
Javascript
<script>
let MAXN = 10000000;
function can(Mid, X, Y, A, B)
{
let p1 = X - Mid * B;
let p2 = Y - Mid * B;
if (p1 < 0 || p2 < 0) {
return false ;
}
let k = A - B;
if (k == 0) {
return true ;
}
let val = Math.floor(p1 / k) + Math.floor(p2 / k);
if (val >= Mid) {
return true ;
}
return false ;
}
function maxPossibleMoves(X, Y, A, B)
{
let ans = 0;
let L = 1,
R = MAXN;
while (L <= R)
{
let Mid = Math.floor((L + R) / 2);
if (can(Mid, X, Y, A, B))
{
L = Mid + 1;
ans = Math.max(ans, Mid);
} else {
R = Mid - 1;
}
}
return ans;
}
let X = 10,
Y = 12,
A = 2,
B = 5;
if (A < B) {
let temp = A;
A = B;
B = temp;
}
document.write(maxPossibleMoves(X, Y, A, B));
</script>
|
Time Complexity: O(log(MAXN)), where MAXN is maximum number of moves
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...