题意:给出一个平面上四个点的坐标,问判断这四个点能组成怎样的四边形,按正方形,矩形,菱形,平行四边形,梯形,普通四边形的顺序判断并输出。
题解:先用凸包把四个点排好序,然后依次判断。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double PI = acos(-1);
const double eps = 1e-9;
struct Point {
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
};
typedef Point Vector;
double Sqr(double x) {
return x * x;
}
double dcmp(double x) {
if (fabs(x) < eps)
return 0;
return x < 0 ? -1 : 1;
}
Vector operator + (const Point& A, const Point& B) {
return Vector(A.x + B.x, A.y + B.y);
}
Vector operator - (const Point& A, const Point& B) {
return Vector(A.x - B.x, A.y - B.y);
}
Vector operator * (const Point& A, double a) {
return Vector(A.x * a, A.y * a);
}
Vector operator / (const Point& A, double a) {
return Vector(A.x / a, A.y / a);
}
double Cross(const Vector& A, const Vector& B) {
return A.x * B.y - A.y * B.x;
}
double Dot(const Vector& A, const Vector& B) {
return A.x * B.x + A.y * B.y;
}
double Length(const Vector& A) {
return sqrt(Dot(A, A));
}
long long Length2(const Vector& A) {
return Dot(A, A);
}
bool operator < (const Point& A, const Point& B) {
return A.x < B.x || (A.x == B.x && A.y < B.y);
}
bool operator == (const Point& A, const Point& B) {
return A.x == B.x && A.y == B.y;
}
int ConvexHull(Point* P, int cnt, Point* res) {
sort(P, P + cnt);
int m = 0;
for (int i = 0; i < cnt; i++) {
while (m > 1 && Cross(res[m - 1] - res[m - 2], P[i] - res[m - 2]) <= 0)
m--;
res[m++] = P[i];
}
int k = m;
for (int i = cnt - 2; i >= 0; i--) {
while (m > k && Cross(res[m - 1] - res[m - 2], P[i] - res[m - 2]) <= 0)
m--;
res[m++] = P[i]; } if (cnt > 1)
m--;
return m;
}
Point P[4], R[4];
int main() {
int t, cas = 1;
scanf("%d", &t);
while (t--) {
scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &P[0].x, &P[0].y, &P[1].x, &P[1].y, &P[2].x, &P[2].y, &P[3].x, &P[3].y);
printf("Case %d: ", cas++);
int cnt = ConvexHull(P, 4, R);
if (cnt < 4) {
printf("Ordinary Quadrilateral\n");
continue;
}
double AB = Length2(R[0] - R[1]);
double BC = Length2(R[1] - R[2]);
double CD = Length2(R[2] - R[3]);
double AD = Length2(R[3] - R[0]);
double AC = Length2(R[0] - R[2]);
double BD = Length2(R[1] - R[3]);
if (dcmp(AB - BC) == 0 && dcmp(AB - CD) == 0 && dcmp(AB - AD) == 0 && dcmp(AD + CD - AC) == 0 && dcmp(CD + BC - BD) == 0 && dcmp(AC - BD) == 0)
printf("Square\n");
else if (dcmp(AB - CD) == 0 && dcmp(AD - BC) == 0 && dcmp(AD + CD - AC) == 0 && dcmp(CD + BC - BD) == 0 && dcmp(AC - BD) == 0)
printf("Rectangle\n");
else if (dcmp(AB - BC) == 0 && dcmp(AB - CD) == 0 && dcmp(AB - AD) == 0 && dcmp(AD + CD - AC) != 0 && dcmp(CD + BC - BD) != 0)
printf("Rhombus\n");
else if (dcmp(AB - CD) == 0 && dcmp(AD - BC) == 0 && dcmp(Cross(R[1] - R[0], R[2] - R[3])) == 0 && dcmp(Cross(R[3] - R[0], R[2] - R[1])) == 0 && dcmp(AD + CD - AC) != 0 && dcmp(CD + BC - BD) != 0)
printf("Parallelogram\n");
else if ((dcmp(Cross(R[1] - R[0], R[2] - R[3])) == 0 && dcmp(Cross(R[3] - R[0], R[2] - R[1])) != 0) || (dcmp(Cross(R[3] - R[0], R[2] - R[1])) == 0 && dcmp(Cross(R[1] - R[0], R[2] - R[3])) != 0))
printf("Trapezium\n");
else
printf("Ordinary Quadrilateral\n");
}
return 0;
}