📌  相关文章
📜  从原点到达给定坐标的字典序第 K 最小方式

📅  最后修改于: 2021-10-23 08:22:27             🧑  作者: Mango

给定一个 2D 平面上的坐标(x, y) 。我们必须从位于原点的当前位置(即 (0, 0))到达 (x, y)。在每一步中,我们都可以在平面上垂直或水平移动。水平移动每一步时我们写“H”,而垂直移动每一步时我们写“V”。因此,可能有许多包含 ‘H’ 和 ‘V’ 的字符串表示从 (0, 0) 到 (x, y) 的路径。任务是找出所有可能的字符串之间的字典序第K个最小的字符串。
例子:

先决条件:从原点到达一个点的方法
方法:思路是用递归来解决问题。从原点到达 (x, y) 的方法数是x + y C x
现在观察,从 (1, 0) 到达 (x, y) 的方式数将是 (x + y – 1, x – 1) 因为我们已经在水平方向上做了一步,所以从X。此外,从 (0, 1) 到达 (x, y) 的方式数将是 (x + y – 1, y – 1) 因为我们已经在垂直方向迈出了一步,所以从 y 中减去 1 .由于“H”在字典序上小于“V”,因此在所有字符串中,起始字符串的开头将包含“H”,即初始移动将是水平的。
因此,如果 K <= x + y – 1 C x – 1 ,我们将采取 ‘H’ 作为第一步,否则我们将采取 ‘V’ 作为第一步并求解从 (1) 到 (x, y) 的次数, 0) 将是 K = K – x + y – 1 C x – 1
下面是这个方法的实现:

C++
// CPP Program to find Lexicographically Kth
// smallest way to reach given coordinate from origin
#include 
using namespace std;
 
// Return (a+b)!/a!b!
int factorial(int a, int b)
{
    int res = 1;
 
    // finding (a+b)!
    for (int i = 1; i <= (a + b); i++)
        res = res * i;
 
    // finding (a+b)!/a!
    for (int i = 1; i <= a; i++)
        res = res / i;
 
    // finding (a+b)!/b!
    for (int i = 1; i <= b; i++)
        res = res / i;
 
    return res;
}
 
// Return the Kth smallest way to reach given coordinate from origin
void Ksmallest(int x, int y, int k)
{
    // if at origin
    if (x == 0 && y == 0)
        return;
 
    // if on y-axis
    else if (x == 0) {
        // decrement y.
        y--;
 
        // Move vertical
        cout << "V";
 
        // recursive call to take next step.
        Ksmallest(x, y, k);
    }
 
    // If on x-axis
    else if (y == 0) {
        // decrement x.
        x--;
 
        // Move horizontal.
        cout << "H";
 
        // recursive call to take next step.
        Ksmallest(x, y, k);
    }
    else {
        // If x + y C x is greater than K
        if (factorial(x - 1, y) > k) {
            // Move Horizontal
            cout << "H";
 
            // recursive call to take next step.
            Ksmallest(x - 1, y, k);
        }
        else {
            // Move vertical
            cout << "V";
 
            // recursive call to take next step.
            Ksmallest(x, y - 1, k - factorial(x - 1, y));
        }
    }
}
 
// Driven Program
int main()
{
    int x = 2, y = 2, k = 2;
 
    Ksmallest(x, y, k);
 
    return 0;
}


Java
// Java Program to find
// Lexicographically Kth
// smallest way to reach
// given coordinate from origin
import java.io.*;
 
class GFG
{
 
// Return (a+b)!/a!b!
static int factorial(int a,
                     int b)
{
    int res = 1;
 
    // finding (a+b)!
    for (int i = 1;
             i <= (a + b); i++)
        res = res * i;
 
    // finding (a+b)!/a!
    for (int i = 1; i <= a; i++)
        res = res / i;
 
    // finding (a+b)!/b!
    for (int i = 1; i <= b; i++)
        res = res / i;
 
    return res;
}
 
// Return the Kth smallest
// way to reach given
// coordinate from origin
static void Ksmallest(int x,
                      int y, int k)
{
    // if at origin
    if (x == 0 && y == 0)
        return;
 
    // if on y-axis
    else if (x == 0)
    {
        // decrement y.
        y--;
 
        // Move vertical
        System.out.print("V");
 
        // recursive call to
        // take next step.
        Ksmallest(x, y, k);
    }
 
    // If on x-axis
    else if (y == 0)
    {
        // decrement x.
        x--;
 
        // Move horizontal.
        System.out.print("H");
 
        // recursive call to
        // take next step.
        Ksmallest(x, y, k);
    }
    else
    {
        // If x + y C x is
        // greater than K
        if (factorial(x - 1, y) > k)
        {
            // Move Horizontal
            System.out.print( "H");
 
            // recursive call to
            // take next step.
            Ksmallest(x - 1, y, k);
        }
        else
        {
            // Move vertical
            System.out.print("V");
 
            // recursive call to
            // take next step.
            Ksmallest(x, y - 1, k -
            factorial(x - 1, y));
        }
    }
}
 
// Driver Code
public static void main (String[] args)
{
    int x = 2, y = 2, k = 2;
 
    Ksmallest(x, y, k);
}
}
 
// This code is contributed
// by anuj_67.


Python3
# Python3 Program to find Lexicographically Kth
# smallest way to reach given coordinate from origin
 
# Return (a+b)!/a!b!
def factorial(a, b):
 
    res = 1
 
    # finding (a+b)!
    for i in range(1, a + b + 1):
        res = res * i
 
    # finding (a+b)!/a!
    for i in range(1, a + 1):
        res = res // i
 
    # finding (a+b)!/b!
    for i in range(1, b + 1):
        res = res // i
 
    return res
 
# Return the Kth smallest way to reach
# given coordinate from origin
def Ksmallest(x, y, k):
 
    # if at origin
    if x == 0 and y == 0:
        return
 
    # if on y-axis
    elif x == 0:
        # decrement y.
        y -= 1
 
        # Move vertical
        print("V", end = "")
 
        # recursive call to take next step.
        Ksmallest(x, y, k)
     
    # If on x-axis
    elif y == 0:
         
        # decrement x.
        x -= 1
 
        # Move horizontal.
        print("H", end = "")
 
        # recursive call to take next step.
        Ksmallest(x, y, k)
     
    else:
         
        # If x + y C x is greater than K
        if factorial(x - 1, y) > k:
             
            # Move Horizontal
            print("H", end = "")
 
            # recursive call to take next step.
            Ksmallest(x - 1, y, k)
         
        else:
             
            # Move vertical
            print("V", end = "")
 
            # recursive call to take next step.
            Ksmallest(x, y - 1, k - factorial(x - 1, y))
         
# Driver Code
if __name__ == "__main__":
 
    x, y, k = 2, 2, 2
    Ksmallest(x, y, k)
 
# This code is contributed by Rituraj Jain


C#
// C# Program to find
// Lexicographically Kth
// smallest way to reach
// given coordinate from origin
using System;
 
class GFG
{
 
// Return (a+b)!/a!b!
static int factorial(int a,
                    int b)
{
    int res = 1;
 
    // finding (a+b)!
    for (int i = 1;
            i <= (a + b); i++)
        res = res * i;
 
    // finding (a+b)!/a!
    for (int i = 1; i <= a; i++)
        res = res / i;
 
    // finding (a+b)!/b!
    for (int i = 1; i <= b; i++)
        res = res / i;
 
    return res;
}
 
// Return the Kth smallest
// way to reach given
// coordinate from origin
static void Ksmallest(int x,
                    int y, int k)
{
    // if at origin
    if (x == 0 && y == 0)
        return;
 
    // if on y-axis
    else if (x == 0)
    {
        // decrement y.
        y--;
 
        // Move vertical
        Console.Write("V");
 
        // recursive call to
        // take next step.
        Ksmallest(x, y, k);
    }
 
    // If on x-axis
    else if (y == 0)
    {
        // decrement x.
        x--;
 
        // Move horizontal.
        Console.Write("H");
 
        // recursive call to
        // take next step.
        Ksmallest(x, y, k);
    }
    else
    {
        // If x + y C x is
        // greater than K
        if (factorial(x - 1, y) > k)
        {
            // Move Horizontal
            Console.Write( "H");
 
            // recursive call to
            // take next step.
            Ksmallest(x - 1, y, k);
        }
        else
        {
            // Move vertical
            Console.Write("V");
 
            // recursive call to
            // take next step.
            Ksmallest(x, y - 1, k -
            factorial(x - 1, y));
        }
    }
}
 
// Driver Code
public static void Main (String[] args)
{
    int x = 2, y = 2, k = 2;
 
    Ksmallest(x, y, k);
}
}
 
// This code is contributed by 29AjayKumar


PHP
 $k)
        {
            // Move Horizontal
            echo("H");
 
            // recursive call to
            // take next step.
            Ksmallest($x - 1, $y, $k);
        }
        else
        {
            // Move vertical
            echo("V");
 
            // recursive call to
            // take next step.
            Ksmallest($x, $y - 1, $k -
            factorial($x - 1, $y));
        }
    }
}
 
// Driver Code
$x = 2; $y = 2;$k = 2;
 
Ksmallest($x, $y, $k);
 
// This code is contributed
// by Code_Mech.
?>


Javascript


输出

HVVH

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程