找到可以形成的平方数

时间:2015-08-04 09:13:35

标签: c algorithm optimization

我对这个问题有些麻烦:

  

"考虑具有整数坐标的NxN点网络。一些   网络节点是白色的,有些是黑色的(黑点是" 1"白点" 0")。使用网络点   与角相同的颜色,可以形成正方形。

     

对于给定的配置,找到可以形成的具有相同数字的网络点的顶点的数量。"

例如:

4(N)

0 1 0 0

0 0 1 1

1 0 0 0

0 1 1 1

enter image description here

它可以只形成一个正方形。输出将是" 1"。

我该如何处理这个问题?显然,在大多数情况下,蛮力都会下降,所以我认为在这里发布代码并不是必要的。

更新:我忘了指定

  

N'LT; = 50

4 个答案:

答案 0 :(得分:1)

我将尝试为您提供一个算法,您希望它可以变成实际的C代码。蛮力方法可能是这样做的:

  1. 对于集合中的每个点,请选择集合中的其他点。
  2. 根据生成的线条,确定正方形中的下一条垂直线是什么,并检查集合中是否存在与所需要的相匹配的点。
  3. 如果找到第三个点(因而是第二个边),则对方块的第三个边重复步骤2.
  4. 最后,如果找到三个有效点,则查看第三个点是否正确连接回原点。如果确实如此,那么你就有了匹配。
  5. 如果在任何这些步骤中出现故障,则将第一个点作为候选者丢弃,然后返回步骤1,选择另一个点。迭代完所有点后,您将找到一个正方形,或确定不存在任何一个。
  6. 更新和改进:

    1. 对于集合中的每个点,与集合中的每个其他点进行比较,寻找两个垂直对角线到其他点。如果找到,则存储它连接的两个点的ID。如果未找到,则从您的集合中永久丢弃此点。这一步将是O(N^2),但我认为无法避免它。

    2. 接下来,迭代“选定的”点(即那些具有一个或多个半平方的点),并检查它们连接的点是否也连接回来另一个选择点。如果是这样,那么你找到了一个正方形。这里的诀窍是你在这里做更多的计算。你只需迭代你已经拥有的状态,这应该比第一步中的计算更快。

    3. 这种方法胜过蛮力方法中的纸浆,因为它只需要计算半平方。计算正方形暴力是O(N^4)事件。这种方法是O(N^2),但实际上可能会更快,因为随着算法的进展,这组点会缩小。

答案 1 :(得分:1)

给定一个正方形的两个点,只能构造3种正方形,如下图所示。对于每种情况,我们可以简单地计算其他两点的坐标。我们可以使用map或者一个简单的标志表来检查这些点是否存在(bool存在[MAX_X] [MAX_Y])并且是否满足“相同的数字规则”。

enter image description here

所以只需枚举所有N * N个案,并检查3种。总体时间复杂度为使用C ++ STL映射的O(N ^ 2 * logN)或使用标志表或C ++ STL unordered_map的O(N ^ 2)。

答案 2 :(得分:1)

首先是一些术语: 网格/网络从左到右水平“x”运行1..N,从上到下垂直地“y”运行。 要找到的正方形具有我们顺时针1..4编号的顶点(角)。 我们称之为TopLeft的第一个角落是垂直(y)值最低的角落;如果有两个(非旋转四边形),则它是具有较低水平(x)值的那个。

算法:扫描所有点并尝试用给定点构造一个quandrangle作为顶点#1,即TopLeft。 这导致以下伪代码:

// for each TopLeft candidate...
for x1 = 1 to N-1 // TopLeft can never have x=N
  for y1 = 1 to N-1 // TopLeft van never have y=N

// scan vertex #2 candidates...
for x2 = x1+1 to N // #2 is always strictly to the right of #1
  for y2 = y1 to N // #2 is never above #1

  // resulting #3 coordinates
  x3  = x2 - (y2 - y1)
  if x3 < 1 then exit 'for y2' // all next y2 will also yield x3<1
  y3 = y2 + (x2 - x1)
  if y3 > N then exit 'for y2' // all next y2 will also yield y3>N

// resulting #4
x4 = x1 - (y2 - y1)
if x4 < 1 then exit 'for y2' // all next y2 will also yield x4<1
y4 = y1 + (x2 - x1)
if y4 > N then exit 'for x2' // all next x2 will also yield y4>N

// colors ok?
if grid(x1,y1)==grid(x2,y2) && grid(x1,y1)==grid(x3,y3) && grid(x1,y1)==grid(x4,y4) then  // FOUND!
  count+=1
endif

next y2
next x2
next y1
next x1

答案 3 :(得分:0)

正方形的对角线垂直相交彼此相等并且等长。因此,连接黑点,并尝试可能的线对 - 无论它们是否成直角。请注意,您可能需要使用某些代数和几何来指定整数坐标并计算距离和交点。

现在,您的改进将取决于如何从该套装中选择一对线条。您可以通过仅选择具有相同长度且没有公共端点的线段(这意味着相同的原点和角度的臂)来实现此目的。