使用数字 A 或 B 可以将 X 和 Y 的最大次数减少到接近 0
给定 4 个整数X, Y, A, B 。在一个动作中,要么将X减少A ,将Y减少B ,要么将X减少B ,将Y减少A 。计算最大可能的移动。给定 4 个整数X, Y, A, B 。一步我们可以使X = X – A和Y = Y – B或 X = X – B和Y = Y – A 。计算最大可能的移动总数。
例子:
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
朴素方法:在X 和 Y 的每个值处,我们可以从 X和 Y的最大值中减去A和B的最大值,并从X和Y的最小值中减去A和B的最小值,直到X和Y保持大于零。
有效的方法:给定的问题可以使用对答案技术的二分搜索来解决。
- 这里的关键思想是,如果对于任意数量的移动N ,如果有可能执行这么多移动,那么我们也可以执行N - 1 移动。
- 所以我们可以对答案进行二分搜索。固定范围L = 1 和R = 10000000(如果有大整数值,请更改此值)并为每个值 mid = ( L + R )/2 检查我们是否可以执行这么多的移动。如果可能,则移位L = mid + 1,否则R = mid – 1。返回最大可能值。
- 要检查任何数字 mid,我们必须至少减少 X 和 Y mid * min( A , B ) 并且对于剩余元素,我们可以计算剩余的总值 | A - B |。如果这些值大于中间值,则增加我们的右侧范围,否则减少左侧范围。
执行:
C++
// C++ Program to implement the above approach
#include
using namespace std;
// Helper function to check if
// we can perform Mid number of moves
#define MAXN 10000000 // MAXN = 1e7
bool can(int Mid, int X, int Y, int A, int B)
{
// Remove atleast Mid * B from both X and Y
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
// If any value is negative return false.
if (p1 < 0 || p2 < 0) {
return false;
}
// Calculate remaining values
int k = A - B;
if (k == 0) {
return true;
}
int val = p1 / k + p2 / k;
// If val >= Mid then it is possible
// to perform this much moves
if (val >= Mid) {
return true;
}
// else return false
return false;
}
int maxPossibleMoves(int X, int Y, int A, int B)
{
// Initialize a variable to store the answer
int ans = 0;
// Fix the left and right range
int L = 1, R = MAXN;
// Binary Search over the answer
while (L <= R) {
// Check for the middle
// value as the answer
int Mid = (L + R) / 2;
if (can(Mid, X, Y, A, B)) {
// It is possible to perform
// this much moves
L = Mid + 1;
// Maximise the answer
ans = max(ans, Mid);
}
else {
R = Mid - 1;
}
}
// Return answer
return ans;
}
// Driver Code
int main()
{
int X = 10, Y = 12, A = 2, B = 5;
// Generalise that A >= B
if (A < B) {
swap(A, B);
}
cout << maxPossibleMoves(X, Y, A, B);
}
Java
// Java program to implement the above approach
import java.io.*;
class GFG{
// Helper function to check if
// we can perform Mid number of moves
static int MAXN = 10000000;
static boolean can(int Mid, int X, int Y,
int A, int B)
{
// Remove atleast Mid * B from both X and Y
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
// If any value is negative return false.
if (p1 < 0 || p2 < 0)
{
return false;
}
// Calculate remaining values
int k = A - B;
if (k == 0)
{
return true;
}
int val = p1 / k + p2 / k;
// If val >= Mid then it is possible
// to perform this much moves
if (val >= Mid)
{
return true;
}
// Else return false
return false;
}
static int maxPossibleMoves(int X, int Y, int A, int B)
{
// Initialize a variable to store the answer
int ans = 0;
// Fix the left and right range
int L = 1, R = MAXN;
// Binary Search over the answer
while (L <= R)
{
// Check for the middle
// value as the answer
int Mid = (L + R) / 2;
if (can(Mid, X, Y, A, B))
{
// It is possible to perform
// this much moves
L = Mid + 1;
// Maximise the answer
ans = Math.max(ans, Mid);
}
else
{
R = Mid - 1;
}
}
// Return answer
return ans;
}
// Driver Code
public static void main(String[] args)
{
int X = 10, Y = 12, A = 2, B = 5;
// Generalise that A >= B
if (A < B)
{
int temp = A;
A = B;
B = temp;
}
System.out.println(maxPossibleMoves(X, Y, A, B));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python Program to implement the above approach
# Helper function to check if
# we can perform Mid number of moves
MAXN = 10000000
def can(Mid, X, Y, A, B):
# Remove atleast Mid * B from both X and Y
p1 = X - Mid * B
p2 = Y - Mid * B
# If any value is negative return false.
if (p1 < 0 or p2 < 0):
return False
# Calculate remaining values
k = A - B
if (k == 0):
return True
val = p1 // k + p2 // k
# If val >= Mid then it is possible
# to perform this much moves
if (val >= Mid):
return True
# else return false
return False
def maxPossibleMoves(X, Y, A, B):
# Initialize a variable to store the answer
ans = 0
# Fix the left and right range
L = 1
R = MAXN
# Binary Search over the answer
while (L <= R):
# Check for the middle
# value as the answer
Mid = (L + R) // 2
if (can(Mid, X, Y, A, B)):
# It is possible to perform
# this much moves
L = Mid + 1
# Maximise the answer
ans = max(ans, Mid)
else:
R = Mid - 1
# Return answer
return ans
# Driver Code
X = 10
Y = 12
A = 2
B = 5
# Generalise that A >= B
if (A < B):
tmp = A
A = B
B = tmp
print(maxPossibleMoves(X, Y, A, B))
# This code is contributed by shivanisinghss2110
C#
// C# program to implement the above approach
using System;
class GFG{
// Helper function to check if
// we can perform Mid number of moves
static int MAXN = 10000000;
static Boolean can(int Mid, int X, int Y,
int A, int B)
{
// Remove atleast Mid * B from both X and Y
int p1 = X - Mid * B;
int p2 = Y - Mid * B;
// If any value is negative return false.
if (p1 < 0 || p2 < 0)
{
return false;
}
// Calculate remaining values
int k = A - B;
if (k == 0)
{
return true;
}
int val = p1 / k + p2 / k;
// If val >= Mid then it is possible
// to perform this much moves
if (val >= Mid)
{
return true;
}
// Else return false
return false;
}
static int maxPossibleMoves(int X, int Y, int A, int B)
{
// Initialize a variable to store the answer
int ans = 0;
// Fix the left and right range
int L = 1, R = MAXN;
// Binary Search over the answer
while (L <= R)
{
// Check for the middle
// value as the answer
int Mid = (L + R) / 2;
if (can(Mid, X, Y, A, B))
{
// It is possible to perform
// this much moves
L = Mid + 1;
// Maximise the answer
ans = Math.Max(ans, Mid);
}
else
{
R = Mid - 1;
}
}
// Return answer
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int X = 10, Y = 12, A = 2, B = 5;
// Generalise that A >= B
if (A < B)
{
int temp = A;
A = B;
B = temp;
}
Console.Write(maxPossibleMoves(X, Y, A, B));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出:
3
时间复杂度: O(log(MAXN)),其中 MAXN 是最大移动次数
辅助空间: O(1)