我需要从一组给定的坐标中找到最大的矩形。
考虑以下坐标在X Y坐标系中给出:
3 10, 3 8, 3 6, 3 4, 3 0, 6 0, 6 4, 6 8, 6 10,如何判断以下坐标是否构成一个矩形 (3,0) (3,4) (6,4) (6,0)
运行时间限制: 0.1 秒
谢谢
我需要从一组给定的坐标中找到最大的矩形。
考虑以下坐标在X Y坐标系中给出:
3 10, 3 8, 3 6, 3 4, 3 0, 6 0, 6 4, 6 8, 6 10,如何判断以下坐标是否构成一个矩形 (3,0) (3,4) (6,4) (6,0)
运行时间限制: 0.1 秒
谢谢
将你的点按'x'坐标分组,每组内按'y'坐标排序。在你的情况下,你会得到两个已排序列表:
3: [0,4,6,8,10]
6: [0,4,8,10]
将两个列表进行交集,你会得到:[0,4,8,10]
其中任意两个都能组成一个矩形:
[0,4] => (3,0), (3,4), (6,0), (6,4)
[0,8] => (3,0), (3,8), (6,0), (6,8)
[4,8] => (3,4), (3,8), (6,4), (6,8)
...
这种解决方案仅适用于正交矩形,也就是边与x、y轴平行的矩形。
对于任意一组点(x1,y1)和(x2,y2),将其视为某个矩形的对角线。如果初始集合中存在点(x1,y2)和(x2,y1),则我们找到了一个矩形。需要注意的是,会存在代表同一矩形的两条对角线,因此我们将最终答案除以2。
这仅适用于平行于x轴或y轴的矩形。
C ++ 伪代码:
answer = 0;
set<pair<int, int>> points;
for(auto i=points.begin(); i!=std::prev(points.end()); i++)
{
for(auto j=i+1; j!=points.end(); j++)
{
pair<int, int> p1 = *i;
pair<int, int> p2 = *j;
if(p1.first == p2.first || p1.second == p2.second)
continue;
pair<int, int> p3 = make_pair(p1.first, p2.second);
pair<int, int> p4 = make_pair(p2.first, p1.second);
if(points.find(p3) != points.end() && points.find(p4) != points.end())
++answer;
}
}
return answer/2;
检查4个点是否组成矩形:
如果满足条件,则应该有a[0] = a[1], a[2] = a[3], a[4] = a[5]
我的方法是:
我的解决方案运行时间为O(n^2),但这只适用于与X轴或Y轴平行的矩形。
以下是我实现上述方法的代码:
def getRectangleCount(coordinate):
n = len(coordinate)
y_count = dict()
ans = 0
for i in range(n):
x, y = coordinate[i]
for j in range(n):
dx = coordinate[j][0]
dy = coordinate[j][1]
if y < dy and x == dx:
ans += y_count.get((y, dy), 0)
y_count[(y, dy)] = y_count.get((y, dy), 0) + 1
return ans
coordinate = [[3, 10], [3, 8], [3, 6], [3, 4], [3, 0], [6, 0], [6, 4], [6, 8], [6, 10]]
print(getRectangleCount(coordinate))
// checks if two floating point numbers are equal within a given
// error to avoid rounding issues
bool is_equal(double a, double b, double e) {
return abs(a - b) < e;
}
// computes the dot product of the vectors ab and ac
double dot_product(Point a, Point b, Point c) {
return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y);
}
// find all rectangles in a given set of coordinate points
List<Rectangle> find_rectangles(List<Point> points) {
List<Rectangle> rectangles;
// sort points in ascending order by first comparing x than y value
sort(points);
for (int a = 0; a < points.size(); ++a)
for (int b = a + 1; a < points.size(); ++b)
for (int c = b + 1; c < points.size(); ++c)
for (int d = c + 1; d < points.size(); ++d)
// check all angles
if (is_equal(dot_product(points[a], points[b], points[c]), 0.0, 1e-7) &&
is_equal(dot_product(points[b], points[a], points[d]), 0.0, 1e-7) &&
is_equal(dot_product(points[d], points[b], points[c]), 0.0, 1e-7) &&
is_equal(dot_product(points[c], points[a], points[d]), 0.0, 1e-7))
// found rectangle
rectangles.add(new Rectangle(points[a], points[c], points[d], points[b]));
return rectangles;
}
解释:
对于给定的点集 A, B, C, D
,要定义一个矩形,我们可以检查所有角度是否为90°,这意味着所有非平行边都是正交的。
由于我们可以通过点积为0来检查此属性,因此这是最有效的方法(而不是计算边长时进行平方根计算)。
首先对点进行排序可避免由于排列组合而多次检查相同的点集。