使用数字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-A,Y=Y-B ,或者X=X-B,Y=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
天真的方法。 在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|的总价值。如果这些值大于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 = 1e7bool can(int Mid,int X,int Y,int A,int B){// Remove atleast Mid * B from both X and Yint 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 valuesint 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 movesif (val >= Mid) {return true;}// else return falsereturn false;}int maxPossibleMoves(int X,int Y,int A,int B){// Initialize a variable to store the answerint ans = 0;// Fix the left and right rangeint L = 1, R = MAXN;// Binary Search over the answerwhile (L <= R) {// Check for the middle// value as the answerint Mid = (L + R) / 2;if (can(Mid, X, Y, A, B)) {// It is possible to perform// this much movesL = Mid + 1;// Maximise the answerans = max(ans, Mid);}else {R = Mid - 1;}}// Return answerreturn ans;}// Driver Codeint main(){int X = 10, Y = 12, A = 2, B = 5;// Generalise that A >= Bif (A < B) {swap(A, B);}cout << maxPossibleMoves(X, Y, A, B);} |
输出。
3
时间复杂度。 O(log(MAXN)),其中MAXN是最大移动次数
辅助空间。 O(1)
读者请注意!现在不要停止学习。掌握竞争性编程的所有重要数学概念。 CP课程的基本数学以适合学生的价格获得所有重要的数学概念。要完成从学习语言到DS Algo以及更多的准备工作,请参考 完整的面试准备课程.
我的个人笔记 arrow_drop_up
保存