给定一组积分坐标,检查给定的所有点是否位于可能的正方形的一侧,使得如此形成的正方形的轴平行于X轴和Y轴。如果这样的正方形可以给出正方形的最小可能边。
假设点数为(0,0)
,(1,1)
,(2,2)
答:方块是不可能的。
假设点数为(0,0)
,(0,2)
,(0,5)
,(0,7)
,`(3,0)。
答案:方块是可能的,边的最小长度是7。
我尝试了它并提出了许多角落案件,似乎不可能单独处理它们。我想知道是否有人可以对这类问题采取更一般化的方法,以及如何思考正确的方向。
提前致谢。
坐标范围:-1000 <= x ,y <= 1000
点数是&lt; = 50
。
新编辑: 还有一个角落案例: (2,0),(0,4),(1,5),(5,3) 答案:长度为5的正方形。正方形的角点是(0,0),(0,5),(5,5),(5,0)
答案 0 :(得分:4)
如果您通过xmin
,xmax
,ymin
和ymax
定义方格,那么所有点都必须位于其中一个坐标上。即如果适用于所有顶点v
:
v.x == xmin || v.x == xmax || v.y == ymin || v.y == ymax
边界的候选者是点的边界矩形的边界。如果计算这些边界,请维护每个边的顶点列表。
如果无法将每个顶点分配给边,则无法创建方形。
现在矩形很可能不是正方形。所以我们需要扩大其最短的一面。如果我们选择了侧面,我们需要选择是否移动最小或最大边缘。这就是关联顶点列表发挥作用的地方。要移动边缘,请检查所有关联的顶点是否也与另一条边相关联。然后移动这个边缘是安全的。如果我们既不能移动最小边缘也不能移动最大边缘,则无法创建正方形。
得到的最小边长是边的距离。
答案 1 :(得分:1)
轴的要求有助于我们进行以下观察
maxX
和minX
。 (其中一个比其他小)maxY
和minY
。 maxX
或minX
的X坐标或匹配maxY
或minY
的Y坐标。 (注意OR。如果有一个点都不匹配,比如前面例子中的(1, 1)
,你有一个反例)。这是一个类似c ++的伪代码来计算这些数量。假设您有一个合适的Point
结构。
bool isSquare(vector<Point> points) {
double maxX = points[0].X;
double minX = points[0].X;
double maxY = points[0].Y;
double minY = points[0].Y;
// set maxX, minX, maxY, minY
for(int i = 0; i < points.size(); i++) {
maxX = max(points[i].X, maxX);
minX = min(points[i].X, minX);
maxY = max(points[i].Y, maxY);
minY = min(points[i].Y, minY);
}
// Finally, find a point which matches neither {maxX, minX, maxY, minY}
for(int i = 0; i < points.size(); i++) {
if (points[i].X != maxX && points[i].X != minX && points[i].Y != maxY && points[i].Y != minY) return false;
}
// We are not done yet!
}
现在通过此代码中的检查确保点至少形成一个矩形,内部矩形没有点。确保矩形是square
是更难的部分。对于那部分,您必须检查:
{maxX, minX}
并且它的Y坐标匹配{maxY, minY}
。如果找到,则需要找到相应边缘上任何其他点的最大距离。 max(maxX-minX, maxY-minY)
。 在为这个角落寻找部分编写伪代码时需要小心,并考虑所有情况。但我认为一旦完成,这最终会给出答案。
答案 2 :(得分:1)
我想在一次通过中想办法做到这一点,但是在这里已经很晚了,我很累,所以......
运行所有元素一次,并记录整个集合的最小和最大x
和y
值。正方形的边长(如果存在)将为max(xmax-xmin, ymax-ymin)
。
再次通过积分。要描述与轴平行的方形,每个点必须
x == xmin || x == xmax || y == ymin || y == ymax
,
即,至少一个坐标必须位于正方形的一侧。如果任何一点失败,那么你没有一个正方形。
我很确定这已经足够了,但是分两步完成它似乎不太理想。这是一个有趣的问题,祝你好运。
答案 3 :(得分:0)
您可以使用Axis Aligned Bounding Box(ABB)的常见概念解决这个问题。给定一组点,计算ABB: 循环遍历所有点并找到最小x,最小y,最大x和最大y。然后,需要针对所有点检查由两个角,左下角(min_x,min_y)和右上角(max,max y)定义的框,以查看它们是否位于其周边。由于坐标是积分的(没有浮点误差),因此很容易做到:对于每个点,x坐标或y坐标必须与AAB的相应坐标匹配,而另一个坐标必须在其他坐标。希望这是有道理的。