这是我正在研究的问题:
N个点放置在坐标平面中。
编写一个程序,计算出我们可以选择三种方式的数量 点,以便它们形成一个直角三角形,其腿平行于 坐标轴。
直角三角形具有一个90度的内角。直角三角形的腿是两个短边。
这是我组织代码的方式。
对于每一点,我都检查了另一点。如果两个点具有匹配的x坐标和不同的y坐标,那么我将遍历这些点以查找具有与新点相同的y坐标和不同的x的点。如果发现,我检查了三个点是否有直角的斜边。
类似地,我对两个点重复了修改,这些点具有匹配的y坐标和不同的x。
该程序可以运行,但是会浪费时间,而且我不确定如何减少它。
这是我的代码:
double distwithoutroot(int x1, int y1, int x2, int y2) {
int xdist = pow((x2 - x1),2);
int ydist = pow((y2 - y1),2);
return xdist + ydist;
}
int main() {
int noofpoints;
cin >> noofpoints;
int xs[100000];
int ys[100000];
int count = 0;
for (int i = 0; i < noofpoints; i++) {
cin >> xs[i] >> ys[i];
}
for (int i = 0; i < noofpoints; i++) {
int main_x_point = xs[i];
int main_y_point = ys[i];
for (int j = 0; j < noofpoints; j++) {
int checkmatchx = xs[j];
int checkmatchy = ys[j];
if (main_x_point == checkmatchx && main_y_point != checkmatchy) {
for (int k = 0; k < noofpoints; k++) {
int secondcheckx = xs[k];
int secondchecky = ys[k];
if (checkmatchy == secondchecky && checkmatchx != secondcheckx) {
int hypotenus = distwithoutroot(main_x_point, main_y_point, secondcheckx, secondchecky);
int perpendicular = distwithoutroot(main_x_point, main_y_point, checkmatchx, checkmatchy);
int base = distwithoutroot(secondcheckx, secondchecky, checkmatchx, checkmatchy);
if (hypotenus== ( perpendicular+ base )) {
count += 1;
}
}
}
}
else if (main_y_point == checkmatchy && main_x_point != checkmatchx) {
for (int k = 0; k < noofpoints; k++) {
int secondcheckx = xs[k];
int secondchecky = ys[k];
if (checkmatchx == secondcheckx && checkmatchy != secondchecky) {
int hypotenus = distwithoutroot(main_x_point, main_y_point, secondcheckx, secondchecky);
int base = distwithoutroot(main_x_point, main_y_point, checkmatchx, checkmatchy);
int perpendicular = distwithoutroot(secondcheckx, secondchecky, checkmatchx, checkmatchy);
if (hypotenus == (perpendicular + base)) {
count += 1;
}
}
}
}
}
cout<<count;
}
答案 0 :(得分:2)
您只需要将所有点放在x和y的两个地图中。运行时间减少为O(N)* O(T),T是同一拐角处三角形的最大值。
答案 1 :(得分:0)
扩展the other answer中的想法。
请注意,无需检查勾股定理。如果三角形有一个水平边和一个垂直边,则它是一个直角三角形。要计算此类三角形的数量,只需要使X和Y坐标等于任何值的点数即可。
因此,一个代码草图:
std::map<int, int> map_x; // for each X, counts the points for which xs = X
std::map<int, int> map_y; // for each Y, counts the points for which ys = Y
for (int i = 0; i < noofpoints; i++)
++map_x[xs[i]];
for (int i = 0; i < noofpoints; i++)
++map_x[ys[i]];
for (int i = 0; i < noofpoints; i++)
count += (map_x[xs[i]] - 1) * (map_y[ys[i]] - 1);
最后一个循环的说明:
迭代所有点,并计算该点在直角位置处的直角三角形的数量。
对于每个点,它知道多少个点具有相同的X和多少个点具有相同的Y(必须减去1来排除相同的点)。这些的每种组合都会给出一个合适的三角形。
顺便说一句,某些三角形可能会退化(面积为零);同样,如果某些点出现两次,则某些三角形可能是相同的。我认为您不应该将这些排除在外。