我有一个 C ++代码,用于计算从具有X,Y坐标的给定点集中可以形成多少个正方形。 5点样本输入如下:
5
0 0
0 2
1 0
2 0
2 2
一个重要的注意事项是,正方形不需要轴对齐。这是一个有效的代码,摘自'codechef.com':
int N = 5;
std::vector<int> arr_x{0, 0, 1, 2, 2};
std::vector<int> arr_y{0, 2, 0, 0, 2};
int flag1 = 0;
int flag2 = 0;
int count = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
flag1 = 0;
flag2 = 0;
int x1 = arr_x[i], y1 = arr_y[i];
int x2 = arr_x[j], y2 = arr_y[j];
int p1_x = x1 - y1 + x2 + y2;
int p2_x = x1 + y1 + x2 - y2;
int p1_y = x1 + y1 - x2 + y2;
int p2_y = -x1 + y1 + x2 + y2;
for (int k = 0; k < N; k++) {
if (2 * arr_x[k] == p1_x && 2 * arr_y[k] == p1_y) {
flag1 = 1;
}
if (2 * arr_x[k] == p2_x && 2 * arr_y[k] == p2_y) {
flag2 = 1;
}
}
if (flag1 && flag2) count++;
}
}
std::cout << count / 2 << std::endl;
我不了解p1_x
,p2_x
,p1_y
,p2_y
的逻辑和含义。如果有人可以给我解释,请这样做。
答案 0 :(得分:4)
第一个循环
for (int i = 0; i < N; i++) {
在所有顶点上迭代。第二个循环
for (int j = i + 1; j < N; j++) {
在i
之后的所有顶点上进行迭代。该算法假定顶点在对角,并计算两个缺失的顶点。
int p1_x = x1 - y1 + x2 + y2;
int p2_x = x1 + y1 + x2 - y2;
int p1_y = x1 + y1 - x2 + y2;
int p2_y = -x1 + y1 + x2 + y2;
为避免浮点运算,该计算不太正确。它应该是(x1 - y1 + x2 + y2) / 2
。之后,将顶点与2
相乘以更正此问题。在最后一个循环中
for (int k = 0; k < N; k++) {
搜索两个缺失的顶点。如果找到顶点,则设置标志。
if (2 * arr_x[k] == p1_x && 2 * arr_y[k] == p1_y) {
flag1 = 1;
}
if (2 * arr_x[k] == p2_x && 2 * arr_y[k] == p2_y) {
flag2 = 1;
}
}
如果找到了两个缺失的顶点,则计算该正方形。
if (flag1 && flag2) count++;
}
}
因为每个平方被计数两次,所以平方数除以2。
std::cout << count / 2 << std::endl;
计算示例:
顶点1是(0,0)。顶点2为(2,0)。然后,两个丢失的顶点分别是(1、1)和(1,-1)。让我们尝试计算:
p1_x = (0 - 0 + 2 + 0) / 2 = 1
p2_x = (0 + 0 + 2 - 0) / 2 = 1
p1_y = (0 + 0 - 2 + 0) / 2 = -1
p2_y = (0 + 0 + 2 + 0) / 2 = 1
结果是两个缺失的顶点。