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

📅  最后修改于: 2021-04-24 19:23:56             🧑  作者: Mango

我们提供了一个2D平面和一个点( XY )。我们必须找到一个矩形( X_1Y_1X_2Y_2 ),使其包含给定的点( XY )。选择的矩形必须满足给定条件\frac{length}{breadth}=\frac{a}{b} 。如果可以使用多个矩形,则必须选择矩形中心与点之间的Euclid距离最小的矩形( XY )。

图像源– 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) 。我们从两个不同的角度来考虑问题XY独立地。我们找出min(n/a, m/b)在将a和b除以它们的gcd后,找到可以保持在(0, 0) to (n, m) 。由于我们必须找到距点的中心距为最小距离的矩形( XY ),因此我们从假设( XY )是我们的中心。然后我们发现X_1X_2通过减去长度的一半加上X 。如果有X_1或者X_2超出范围,然后我们相应地移动坐标以使其进入范围(0, 0) to (n, m) 。同样,我们继续计算Y_1Y_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
?>


输出 :

12 0 27 9