我构建了以下代码来读取4对坐标来计算它是否为正方形:
#include <iostream>
using namespace std;
struct {
int x;
int y;
}a[10];
int dist(int x1, int y1, int x2, int y2)
{
// function to compute the (square of the) distance between two points
int c1, c2;
c1 = x2-x1;
c2 = y2-y1;
return (c1*c1)+(c2*c2);
}
int main()
{
int d1, d2, d3, d4;
for (int i=1; i<=4; i++)
{
cout << 'X' << i << '='; cin >> a[i].x;
cout << 'Y' << i << '='; cin >> a[i].y;
}
d1 = dist(a[1].x, a[1].y, a[2].x, a[2].y);
d2 = dist(a[2].x, a[2].y, a[3].x, a[3].y);
d3 = dist(a[3].x, a[3].y, a[4].x, a[4].y);
d4 = dist(a[4].x, a[4].y, a[1].x, a[1].y);
if(d1==d2 && d1==d3 && d1==d4)
cout << "Is a square";
else
cout << "Is not a square";
return 0;
}
代码运行良好,但我想读取多个坐标(超过四个),并检查四个点的每个可能组合,看看它们是否形成正方形。
我无法弄清楚如何扩展上述方法以使用超过四个点作为输入(并从中选择所有四个组合);请有人给我一个提示/手吗?
答案 0 :(得分:0)
这听起来像是一个完整的图形问题。由于所有点都是int,我可以想到的一件事是进行深度优先搜索,没有重复,距离^ 2作为权重。而且你需要一个双伪图来保持角度信息(一个布尔值足以直角v.s.非直角)。
从点0开始,步进到最近的邻居1,然后从邻居1开始,找到它的邻居2,3,4 ...,并按两个标准过滤:距离和角度。每次深度优先搜索最多只需要4步,因为只有4个边。
遍历所有点和预订访问点,您可以跟踪在此期间制作的广场数量。
答案 1 :(得分:0)
以下是一些检查四个点的所有组合以查看它们是否为正方形的代码。请注意,您测试“方形”的原始方法是错误的 - 首先,即使以正确的顺序给出点,钻石形状(错误地)也会被称为“方形”;第二,如果以“错误”的顺序给出点数,则正方形可能看起来不正方形。
我解决了这两个问题。另外,我创建了一个简单的嵌套循环,它可以生成四个点的所有可能组合并对它们进行测试;这可以提高效率(例如,如果点1,2和3不形成“等腰直角三角形”,那么测试第四点是没有意义的 - 所以你可以通过不测试所有时间来节省大量时间其他可能的点)。我将把它留下一段时间。
我没有费心去编写代码的“输入N点”部分 - 我不认为那是你在努力的方面。如果我认为这是错误的,请告诉我。
#include <iostream>
typedef struct{
int x;
int y;
} point;
int isSquare (point *p1, point *p2, point *p3, point *p4) {
double dx, dy;
double dd[6];
point *pp[4];
pp[0]=p1; pp[1]=p2; pp[2]=p3; pp[3]=p4;
int ii, jj, kk, nn;
kk = 0;
// loop over all combinations of first and second point
// six in all
for(ii=0; ii<3; ii++) {
for(jj=ii+1; jj<4; jj++) {
dx = pp[ii]->x - pp[jj]->x;
dy = pp[ii]->y - pp[jj]->y;
dd[kk]= dx*dx + dy*dy;
if (dd[kk]==0) return 0; // two identical points: not a square
if(kk>1) {
for(nn= 0; nn < kk-1; nn++) {
// if both are "sides", we expect their length to be the same;
// if one is a diagonal and the other a side, their ratio is 2
// since we are working with the square of the number
if (!(((2*dd[nn] == dd[kk] ) || (dd[nn] == dd[kk]) || 2*dd[kk] == dd[nn] ))) return 0;
}
}
kk++;
}
}
return 1; // got here: all combinations tested OK, we have a square
}
int main(void) {
// pick ten numbers - chosen so there are two squares
point p[10]={{1,2},{3,2},{1,4},{7,8},{2,4},{3,4},{6,7},{8,7},{2,5},{3,5}};
double d2[10][10];
int ii, jj, kk, ll;
// loop over all possible combinations:
// since there are just four to pick we can hard-wire the loop
for(ii=0; ii<7; ii++) {
for(jj = ii+1; jj<8; jj++) {
for(kk = jj+1; kk<9; kk++) {
for(ll = kk+1; ll<10; ll++) {
if(isSquare(p+ii, p+jj, p+kk, p+ll)) {
std::cout << "combination: " << ii << "," << jj << "," << kk << "," << ll << " is a square\n";
}
}
}
}
}
}
输出:
combination: 0,1,2,5 is a square
combination: 4,5,8,9 is a square