我对这个问题有些麻烦:
"考虑具有整数坐标的NxN点网络。一些 网络节点是白色的,有些是黑色的(黑点是" 1"白点" 0")。使用网络点 与角相同的颜色,可以形成正方形。
对于给定的配置,找到可以形成的具有相同数字的网络点的顶点的数量。"
例如:
4(N)
0 1 0 0
0 0 1 1
1 0 0 0
0 1 1 1
它可以只形成一个正方形。输出将是" 1"。
我该如何处理这个问题?显然,在大多数情况下,蛮力都会下降,所以我认为在这里发布代码并不是必要的。
更新:我忘了指定
N'LT; = 50
答案 0 :(得分:1)
我将尝试为您提供一个算法,您希望它可以变成实际的C代码。蛮力方法可能是这样做的:
更新和改进:
对于集合中的每个点,与集合中的每个其他点进行比较,寻找两个垂直对角线到其他点。如果找到,则存储它连接的两个点的ID。如果未找到,则从您的集合中永久丢弃此点。这一步将是O(N^2)
,但我认为无法避免它。
接下来,迭代“选定的”点(即那些具有一个或多个半平方的点),并检查它们连接的点是否也连接回来另一个选择点。如果是这样,那么你找到了一个正方形。这里的诀窍是你不在这里做更多的计算。你只需迭代你已经拥有的状态,这应该比第一步中的计算更快。
这种方法胜过蛮力方法中的纸浆,因为它只需要计算半平方。计算正方形暴力是O(N^4)
事件。这种方法是O(N^2)
,但实际上可能会更快,因为随着算法的进展,这组点会缩小。
答案 1 :(得分:1)
给定一个正方形的两个点,只能构造3种正方形,如下图所示。对于每种情况,我们可以简单地计算其他两点的坐标。我们可以使用map或者一个简单的标志表来检查这些点是否存在(bool存在[MAX_X] [MAX_Y])并且是否满足“相同的数字规则”。
所以只需枚举所有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)
正方形的对角线垂直相交且彼此相等并且等长。因此,连接黑点,并尝试可能的线对 - 无论它们是否成直角。请注意,您可能需要使用某些代数和几何来指定整数坐标并计算距离和交点。
现在,您的改进将取决于如何从该套装中选择一对线条。您可以通过仅选择具有相同长度且没有公共端点的线段(这意味着相同的原点和角度的臂)来实现此目的。