使用数字A或B,X和Y的最大次数可以减少到接近0

218 阅读3分钟

使用数字A或B,X和Y的最大次数可以减少到接近0

  • 最后更新 : 2021年8月10日

给出4个整数X、Y、A、B,在一次移动中,要么将X 减去 A,将Y 减去B,要么将X减去B,将Y减去A,计算最大可能的移动。给出4个整数X, Y, A, B. 在一步棋中,我们可以使X=X-AY=Y-B ,或者X=X-BY=Y-A,计算最大的总可能动作。

例子。

输入。 X = 10, Y = 12, A = 2, B = 5
**输出。**3
解释。第一步棋。X=8,用A减去X,用B减去Y后,Y=7
第2步:X=8,用A减去Y后,Y=2。第2步:用A减去X,用B减去Y,X=6,Y=2
第3步:用A减去X,用B减去Y,X=1,Y=0。X=1,Y=0,用B减去X,用A减去Y
所以总共可以进行3步。

**输入。**X = 1, Y = 1, A = 2, B = 2
**输出。**0

天真的方法。XY的每个值中,我们可以从XY 的最大值中减去AB的最大值,从XY的最小值中减去AB的最小值,直到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|的总价值。如果这些值大于mid,则增加我们的右边范围,否则减少左边范围。

实现。

C++

// C++ Program to implement the above approach
#include <bits/stdc++.h>
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);
}

输出。

3

时间复杂度。 O(log(MAXN)),其中MAXN是最大移动次数
辅助空间。 O(1)

读者请注意!现在不要停止学习。掌握竞争性编程的所有重要数学概念。 CP课程的基本数学以适合学生的价格获得所有重要的数学概念。要完成从学习语言到DS Algo以及更多的准备工作,请参考 完整的面试准备课程.

我的个人笔记 arrow_drop_up

保存