UVa11800 - Determine the Shape(形状的判断)

题目链接

分析:
我先进行了点的排序,
在画出了所有点的排列状况后,我用线段相交的判断把点换成了这样

if (XiangJiao(A,B,C,D)) swap(B,C);
if (XiangJiao(A,D,B,C)) swap(C,D);

这里写图片描述

之后直接判断边和角的关系就好了:

  • Square(正方形)
    所有的边相等,所有的角相等(等于90°,Dot=0)
  • Rectangle(矩形)
    对边相等,所有的角相等(等于90°,Dot=0)
  • Rhombus(菱形)
    所有边相等,对角相等
  • Parallelogram(平行四边形)
    对边相等,对角相等
  • Trapezium(梯形)
    有一组对边平行

按照以上的顺序判断即可

//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>

using namespace std;

const double eps=1e-8;
struct node{
    double x,y;
    node (double xx=0,double yy=0)
    {
        x=xx;y=yy;
    }
};

node operator + (const node &a,const node &b){return node(a.x+b.x,a.y+b.y);}
node operator - (const node &a,const node &b){return node(a.x-b.x,a.y-b.y);}
node operator * (const node &a,const double &b){return node(a.x*b,a.y*b);}
node operator / (const node &a,const double &b){return node(a.x/b,a.y/b);}
node operator < (const node &a,const node &b){return a.x<b.x||(a.x==b.x && a.y<b.y);}
node operator == (const node &a,const node &b){return a.x==b.x && a.y==b.y;}

int dcmp(double x)
{
    if (fabs(x)<eps) return 0;
    else if (x>0 ) return 1;
    else return -1;
}

double Cross(node x,node y){return x.x*y.y-x.y*y.x;}
double Dot(node x,node y){return x.x*y.x+x.y*y.y;}

double Len(node x) {return sqrt(Dot(x,x));}
double Angle(node A,node B,node C)
{
    if (dcmp(Dot(A-B,C-B))==0) return 0;                       //90° 
    return acos( Dot(A-B,C-B) / Len(A-B) / Len(C-B) );
}

bool XiangJiao(node a1,node a2,node b1,node b2)
{
    double c1=Cross(a2-a1,b1-a1);
    double c2=Cross(a2-a1,b2-a1);
    double c3=Cross(b2-b1,a1-b1);
    double c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}

int main()
{
    int T;
    node A,B,C,D;
    scanf("%d",&T);
    for (int cas=1;cas<=T;cas++)
    {
        printf("Case %d: ",cas);

        scanf("%lf%lf",&A.x,&A.y);
        scanf("%lf%lf",&B.x,&B.y);
        scanf("%lf%lf",&C.x,&C.y);
        scanf("%lf%lf",&D.x,&D.y);

        if (XiangJiao(A,B,C,D)) swap(B,C);
        if (XiangJiao(A,D,B,C)) swap(C,D);

        double l1=Len(B-A);
        double l2=Len(C-B);
        double l3=Len(D-C);
        double l4=Len(A-D);

        double a=Angle(D,A,B);
        double b=Angle(A,B,C);
        double c=Angle(B,C,D);
        double d=Angle(C,D,A);

        if (dcmp(a-b)==0&&dcmp(b-c)==0&&dcmp(c-d)==0&&dcmp(l1-l2)==0&&dcmp(l2-l3)==0&&dcmp(l3-l4)==0)          //边角都相等 
        {
            printf("Square\n");
            continue;
        }
        else if (dcmp(a-b)==0&&dcmp(b-c)==0&&dcmp(c-d)==0&&dcmp(l1-l3)==0&&dcmp(l2-l4)==0)                     //对边相等 
        {
            printf("Rectangle\n");
            continue;
        }
        else if (dcmp(l1-l2)==0&&dcmp(l2-l3)==0&&dcmp(l3-l4)==0&&dcmp(a-c)==0&&dcmp(b-d)==0)                   //四边相等 
        {
            printf("Rhombus\n");
            continue;
        }
        else if (dcmp(l1-l3)==0&&dcmp(l2-l4)==0&&dcmp(a-c)==0&&dcmp(b-d)==0)                                  //对边相等 
        {
            printf("Parallelogram\n");
            continue;
        }
        else if (dcmp(Cross(D-A,B-C))==0||dcmp(Cross(B-A,C-D))==0)                                            //有两边平行 
        {
            printf("Trapezium\n");
            continue;
        }
        else
        {
            printf("Ordinary Quadrilateral\n");
            continue;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值