给定两个正整数X和Y ,任务是找出点(X, Y) 是否可以从点(0, 0)到达点 (X, Y),使得在每次第 i 次移动中,x 坐标或 y 坐标可以增加3我。如果可能,则打印Yes 。否则,打印No 。
例子:
Input: X = 1, Y = 3
Output: Yes
Explanation:
Following are the steps from (0, 0) to (1, 3):
Step 0: Increment the X coordinate by 30(= 1) modifies the coordinates to (1, 0).
Step 1: Increment the Y coordinate by 31(= 2) modifies the coordinates to (1, 3).
Therefore, the coordinates (1, 3) can be reached from (0, 0). Hence, print Yes.
Input: X = 10, Y = 30
Output: Yes
朴素的方法:解决给定问题的最简单的方法是通过在每个第 i 步中递减 3 i来从 (X, Y)生成所有可能的移动,并检查任何此类移动组合是否达到(0, 0) 。如果可能,则打印Yes 。否则,打印No 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find whether (0, 0) can
// be reached from (X, Y) by decrementing
// 3^i at each ith step
bool canReach(int X, int Y, int steps)
{
// Termination Condition
if (X == 0 && Y == 0) {
return true;
}
if (X < 0 || Y < 0) {
return false;
}
// Otherwise, recursively call by
// decrementing 3^i at each step
return (
canReach(X - (int)pow(3, steps),
Y, steps + 1)
| canReach(X, Y - (int)pow(3, steps),
steps + 1));
}
// Driver Code
int main()
{
int X = 10, Y = 30;
if (canReach(X, Y, 0)) {
cout << "YES" << endl;
}
else
cout << "NO" << endl;
return 0;
}
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find whether (0, 0) can
// be reached from (X, Y) by decrementing
// 3^i at each ith step
bool canReach(int X, int Y)
{
// Stores the number of steps
// performed to reach (X, Y)
int steps = 0;
while (X || Y) {
// Value of X in base 3
int pos1 = X % 3;
// Value of Y in base 3
int pos2 = Y % 3;
// Check if any has value 2
if (pos1 == 2 || pos2 == 2) {
return false;
}
// If both have value 1
if (pos1 == 1 && pos2 == 1) {
return false;
}
// If both have value 0
if (pos1 == 0 && pos2 == 0) {
return false;
}
X /= 3;
Y /= 3;
steps++;
}
// Otherwise, return true
return true;
}
// Driver Code
int main()
{
int X = 10, Y = 30;
if (canReach(X, Y)) {
cout << "YES";
}
else {
cout << "NO";
}
}
YES
时间复杂度: O(2 K ),其中 K 是执行的最大步骤数。
辅助空间: O(1)
高效的方法:通过将 X 和 Y 转换为基数 3,可以根据以下观察结果优化上述方法:
- 如果基数为 3 的 X 和 Y 的值都为 1 ,则无法到达 (X, Y),因为无法在两个方向上执行此步骤。
- 如果以 3 为底的 X 和 Y 的任何值中都有 2 ,则无法达到 (X, Y),因为这无法用 3 的完美幂表示。
- 如果基数为 3 的 X 和 Y 的任何值都为 0 ,则无法到达 (X, Y),因为除了最后一步之外,无法执行此步骤。
- 否则,在所有剩余的情况下 (X, Y) 都可以从 (0, 0) 到达。
根据上述观察,相应地打印结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find whether (0, 0) can
// be reached from (X, Y) by decrementing
// 3^i at each ith step
bool canReach(int X, int Y)
{
// Stores the number of steps
// performed to reach (X, Y)
int steps = 0;
while (X || Y) {
// Value of X in base 3
int pos1 = X % 3;
// Value of Y in base 3
int pos2 = Y % 3;
// Check if any has value 2
if (pos1 == 2 || pos2 == 2) {
return false;
}
// If both have value 1
if (pos1 == 1 && pos2 == 1) {
return false;
}
// If both have value 0
if (pos1 == 0 && pos2 == 0) {
return false;
}
X /= 3;
Y /= 3;
steps++;
}
// Otherwise, return true
return true;
}
// Driver Code
int main()
{
int X = 10, Y = 30;
if (canReach(X, Y)) {
cout << "YES";
}
else {
cout << "NO";
}
}
YES
时间复杂度: O(log 3 (max(X, Y))
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。