给一个四边形的顶点坐标,判断它属于哪种四边形:Square(正方形),Rectangle(矩形),Rhombus(菱形),Parallelogram(平行四边形),Trapezium(梯形),Ordinary Quadrilateral(普通四边形)。
题外话:最近开始搞几何了(会搞几何队友要去考研了 = = 只能自己挑了)
一个几何的基础题,根据特性逐个判断即可。
由于前面4种都是平行四边形,所以,先根据平行边的对数找出平行四边形(2对),梯形(1对)和普通四边形(0对)。
利用叉积为0判断平行,由于给定的点没有顺序,所以可以先固定一个点,遍历剩下三个点,看看哪个和它组合能够与剩下两个平行,这样就可以先找出一对平行边,然后再判断是否有另一对。
如果是平行四边形就再根据它们各自的几何特性(直角+对角线垂直)判断即可。
#include<cstdio>
#include<algorithm>
using namespace std;
int t, ct, x[4], y[4];
int dot(int x1, int y1, int x2, int y2){//点积
return x1*x2+y1*y2;
}
int cross(int x1, int y1, int x2, int y2){//叉积
return x1*y2-x2*y1;
}
int parall(){//寻找平行边对数
int dx1, dy1, dx2, dy2;
bool flag=0;
for(int i=1; i<4; i++){
dx1 = x[i]-x[0];
dy1 = y[i]-y[0];
swap(x[i], x[1]);
swap(y[i], y[1]);
dx2 = x[3]-x[2];
dy2 = y[3]-y[2];
if(cross(dx1, dy1, dx2, dy2)==0){
flag=1;
break;
}
swap(x[i], x[1]);
swap(y[i], y[1]);
}
if(!flag) return 0;
dx1 = x[2]-x[0];
dy1 = y[2]-y[0];
dx2 = x[3]-x[1];
dy2 = y[3]-y[1];
if(cross(dx1, dy1, dx2, dy2)==0){
return 2;
}
swap(x[2], x[3]);
swap(y[2], y[3]);
dx1 = x[2]-x[0];
dy1 = y[2]-y[0];
dx2 = x[3]-x[1];
dy2 = y[3]-y[1];
if(cross(dx1, dy1, dx2, dy2)==0){
return 2;
}
return 1;
}
bool Right(){//判断直角
return dot(x[1]-x[0], y[1]-y[0], x[2]-x[0], y[2]-y[0])==0;
}
bool vertical(){//对角线垂直(判断菱形和正方形,用边相等也可以,但相当于求两次点积)
return dot(x[3]-x[0], y[3]-y[0], x[2]-x[1], y[2]-y[1])==0;
}
int main(){
scanf("%d",&t);
for(ct=1; ct<=t; ct++){
for(int i=0; i<4; i++) scanf("%d %d", x+i, y+i);
printf("Case %d: ", ct);
int pa = parall();
if(pa==2){
if(Right()){
if(vertical()) puts("Square");
else puts("Rectangle");
}
else{
if(vertical()) puts("Rhombus");
else puts("Parallelogram");
}
}
else if(pa==1){
puts("Trapezium");
}
else{
puts("Ordinary Quadrilateral");
}
}
return 0;
}