📜  寻找覆盖给定点的最佳拟合矩形

📅  最后修改于: 2021-06-01 01:59:02             🧑  作者: Mango

我们提供了一个2D平面和一个点( X  Y  )。我们必须找到一个矩形( X_1  Y_1  X_2  Y_2  )这样
包含给定的点( X  Y  )。选择的矩形必须满足给定条件\frac{length}{breadth}=\frac{a}{b}  。如果
可能有多个矩形,我们必须选择矩形中心与点之间的Euclid距离最小的矩形( X  Y  )。

图像源– Codeforce
例子 :

Input : 70 10 20 5 5 3
Output :12 0 27 9

Input :100 100 32 63 2 41
Output :30 18 34 100

问题背后的逻辑如下。首先我们减少\frac{a}{b}  通过将a和b除以最小的不可约形式gcd(a, b)  。我们从两个不同的角度来考虑问题X  Y  独立地。我们找出min(n/a, m/b)  在将a和b除以它们的gcd后,找到可以保持在(0, 0) to (n, m)  。由于我们必须找到距点的中心距为最小距离的矩形( X  Y  ),因此我们从假设( X  Y  )是我们的中心。然后我们发现X_1  X_2  通过减去长度的一半加上X  。如果有X_1  或者X_2  超出范围,然后我们相应地移动坐标以使其进入范围(0, 0) to (n, m)  。同样,我们继续计算Y_1  Y_2
对于根据上述逻辑的第一个示例,答案是12, 0, 27, 9

C++
#include 
#include 
using namespace std;
 
// Function to calculate
// GCD of a and b
int gcd(int a, int b)
{
    if (a == 0)
        return b;
    else
        return gcd(b % a, a);
}
 
// Function to calculate the
// coordinates of the rectangle
void solve(int n, int m, int x, int y, int a, int b)
{
 
    int k, g;
    int x1, y1, x2, y2;
    g = gcd(a, b);
 
    // Reducing the ratio to
    // lowest irreducible form
    a /= g;
    b /= g;
 
    // Finding the maximum multiple
    // of length that can be chosen
    k = min(n / a, m / b);
 
    // Assuming the point (X, Y) as the
    // centre of the required rectangle
    // Finding the lower X coordinate by
    // subtracting half of total length from X
    x1 = x - (k * a - k * a / 2);
 
    // Finding the upper X coordinate
    // by adding half of total length to X
    x2 = x + k * a / 2;
 
    // Finding lower Y coordinate by
    // subtracting half of breadth from Y
    y1 = y - (k * b - k * b / 2);
 
    // Finding upper Y coordinate
    // by adding half of breadth to Y
    y2 = y + k * b / 2;
 
    // If lower X coordinate
    // goes below 0 then we shift
    // the lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if (x1 < 0) {
        x2 -= x1;
        x1 = 0;
    }
 
    // If upper X coordinate goes
    // beyond n, then we shift the
    // upper X coordinate ton
    // and we shift the lower coordinate
    // accordingly to bring the upper
    // coordinate in range
    if (x2 > n) {
        x1 -= x2 - n;
        x2 = n;
    }
 
    // If lower Y coordinate goes
    // below 0 then we shift the
    // lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if (y1 < 0) {
        y2 -= y1;
        y1 = 0;
    }
 
    // If upper Y coordinate goes
    // beyond n, then we shift the
    // upper X coordinate
    // to n and we shift the lower
    // coordinate accordingly to
    // bring the upper
    // coordinate in range
    if (y2 > m) {
        y1 -= y2 - m;
        y2 = m;
    }
 
    cout << x1 << " " << y1 << " " << x2
         << " " << y2 << endl;
}
 
// Driver function
int main()
{
    int n = 70, m = 10, x = 20, y = 5, a = 5, b = 3;
    solve(n, m, x, y, a, b);
    return 0;
}


Java
class GFG {
 
    // Function to calculate
    // GCD of a and b
    public static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        else
            return gcd(b % a, a);
    }
 
    // Function to calculate the
    // coordinates of the rectangle
    public static void solve(int n, int m,
                             int x, int y,
                             int a, int b)
    {
 
        int k, g;
        int x1, y1, x2, y2;
        g = gcd(a, b);
 
        // Reducing the ratio to
        // lowest irreducible form
        a /= g;
        b /= g;
 
        // Finding the maximum multiple
        // of length that can be chosen
        k = Math.min(n / a, m / b);
 
        // Assuming the point (X, Y) as the
        // centre of the required rectangle
        // Finding the lower X coordinate by
        // subtracting half of total length
        // from X
        x1 = x - (k * a - k * a / 2);
 
        // Finding the upper X coordinate
        // by adding half of total length
        // to X
        x2 = x + k * a / 2;
 
        // Finding lower Y coordinate by
        // subtracting half of breadth
        // from Y
        y1 = y - (k * b - k * b / 2);
 
        // Finding upper Y coordinate
        // by adding half of breadth
        // to Y
        y2 = y + k * b / 2;
 
        // If lower X coordinate
        // goes below 0 then we shift
        // the lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (x1 < 0) {
            x2 -= x1;
            x1 = 0;
        }
 
        // If upper X coordinate goes
        // beyond n, then we shift the
        // upper X coordinate ton
        // and we shift the lower coordinate
        // accordingly to bring the upper
        // coordinate in range
        if (x2 > n) {
            x1 -= x2 - n;
            x2 = n;
        }
 
        // If lower Y coordinate goes
        // below 0 then we shift the
        // lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (y1 < 0) {
            y2 -= y1;
            y1 = 0;
        }
 
        // If upper Y coordinate goes
        // beyond n, then we shift the
        // upper X coordinate
        // to n and we shift the lower
        // coordinate accordingly to
        // bring the upper
        // coordinate in range
        if (y2 > m) {
            y1 -= y2 - m;
            y2 = m;
        }
 
        System.out.println(x1 + " " + y1 + " " + x2
                           + " " + y2);
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int n = 70, m = 10;
        int x = 20, y = 5;
        int a = 5, b = 3;
        solve(n, m, x, y, a, b);
    }
}
 
// This code is contributed by - vkz6198


Python 3
# Function to calculate
# GCD of a and b
def gcd(a, b):
 
    if (a == 0):
        return b
    else:
        return gcd(b % a, a)
 
# Function to calculate the
# coordinates of the rectangle
def solve(n, m, x, y, a, b):
 
    g = int(gcd(a, b))
 
    # Reducing the ratio to
    # lowest irreducible form
    a /= g
    b /= g
 
    # Finding the maximum multiple
    # of length that can be chosen
    k = int(min(n / a, m / b))
 
    # Assuming the point (X, Y) as the
    # centre of the required rectangle
    # Finding the lower X coordinate by
    # subtracting half of total length
    # from X
    x1 = int(x - (k * a - k * a / 2))
 
    # Finding the upper X coordinate
    # by adding half of total length
    # to X
    x2 = int(x + k * a / 2)
 
    # Finding lower Y coordinate by
    # subtracting half of breadth from Y
    y1 = int(y - (k * b - k * b / 2))
 
    # Finding upper Y coordinate
    # by adding half of breadth to Y
    y2 = int(y + k * b / 2)
 
    # If lower X coordinate
    # goes below 0 then we shift
    # the lower coordinate to 0
    # and the upper coordinate
    # accordingly to bring lower
    # coordinate in range
    # and to keep center as
    # close as possible to X, Y
    if (int(x1) < 0):
        x2 -= x1
        x1 = 0
     
 
    # If upper X coordinate goes
    # beyond n, then we shift the
    # upper X coordinate ton
    # and we shift the lower coordinate
    # accordingly to bring the upper
    # coordinate in range
    if (int(x2) > n):
        x1 -= x2 - n
        x2 = n
     
 
    # If lower Y coordinate goes
    # below 0 then we shift the
    # lower coordinate to 0
    # and the upper coordinate
    # accordingly to bring lower
    # coordinate in range
    # and to keep center as
    # close as possible to X, Y
    if (int(y1) < 0) :
        y2 -= y1
        y1 = 0
     
 
    # If upper Y coordinate goes
    # beyond n, then we shift the
    # upper X coordinate
    # to n and we shift the lower
    # coordinate accordingly to
    # bring the upper
    # coordinate in range
    if (int(y2) > m):
        y1 -= y2 - m
        y2 = m
     
 
    print(x1 , " " , y1 , " " , x2
        , " " , y2,sep="")
 
# Driver function
n = 70
m = 10
x = 20
y = 5
a = 5
b = 3
solve(n, m, x, y, a, b)
 
# This code is contributed by Smitha


C#
using System;
 
class GFG {
 
    // Function to calculate
    // GCD of a and b
    public static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        else
            return gcd(b % a, a);
    }
 
    // Function to calculate the
    // coordinates of the rectangle
    public static void solve(int n, int m,
                            int x, int y,
                            int a, int b)
    {
 
        int k, g;
        int x1, y1, x2, y2;
        g = gcd(a, b);
 
        // Reducing the ratio to
        // lowest irreducible form
        a /= g;
        b /= g;
 
        // Finding the maximum multiple
        // of length that can be chosen
        k = Math.Min(n / a, m / b);
 
        // Assuming the point (X, Y) as the
        // centre of the required rectangle
        // Finding the lower X coordinate by
        // subtracting half of total length
        // from X
        x1 = x - (k * a - k * a / 2);
 
        // Finding the upper X coordinate
        // by adding half of total length
        // to X
        x2 = x + k * a / 2;
 
        // Finding lower Y coordinate by
        // subtracting half of breadth
        // from Y
        y1 = y - (k * b - k * b / 2);
 
        // Finding upper Y coordinate
        // by adding half of breadth
        // to Y
        y2 = y + k * b / 2;
 
        // If lower X coordinate
        // goes below 0 then we shift
        // the lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (x1 < 0) {
            x2 -= x1;
            x1 = 0;
        }
 
        // If upper X coordinate goes
        // beyond n, then we shift the
        // upper X coordinate ton
        // and we shift the lower coordinate
        // accordingly to bring the upper
        // coordinate in range
        if (x2 > n) {
            x1 -= x2 - n;
            x2 = n;
        }
 
        // If lower Y coordinate goes
        // below 0 then we shift the
        // lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (y1 < 0) {
            y2 -= y1;
            y1 = 0;
        }
 
        // If upper Y coordinate goes
        // beyond n, then we shift the
        // upper X coordinate
        // to n and we shift the lower
        // coordinate accordingly to
        // bring the upper
        // coordinate in range
        if (y2 > m) {
            y1 -= y2 - m;
            y2 = m;
        }
 
        Console.Write(x1 + " " + y1 +
                 " " + x2 + " " + y2);
    }
 
    // Driver Code
    public static void Main()
    {
        int n = 70, m = 10;
        int x = 20, y = 5;
        int a = 5, b = 3;
        solve(n, m, x, y, a, b);
    }
}
 
// This code is contributed by Smitha


PHP
 $n)
    {
        $x1 -= $x2 - $n;
        $x2 = $n;
    }
 
    // If lower Y coordinate goes
    // below 0 then we shift the
    // lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if ($y1 < 0)
    {
        $y2 -= $y1;
        $y1 = 0;
    }
 
    // If upper Y coordinate goes
    // beyond n, then we shift the
    // upper X coordinate
    // to n and we shift the lower
    // coordinate accordingly to
    // bring the upper
    // coordinate in range
    if ($y2 > $m)
    {
        $y1 -= $y2 - $m;
        $y2 = $m;
    }
 
    echo $x1, " ", $y1, " ",
         $x2, " ", $y2, "\n";
}
 
// Driver Code
$n = 70; $m = 10; $x = 20;
$y = 5; $a = 5; $b = 3;
solve($n, $m, $x, $y, $a, $b);
 
// This code is contributed by aj_36
?>


Javascript


输出 :

12 0 27 9