hihoCoder1040 : 矩形判断

简述

  大体思路是可以出来的,就是先判断能否组成四边形,然后再判断能否组成矩形。
  四边形这部分比较难搞,但是我们有 stl 啊, 直接自定义一个小于号,然后把所有的点扔进 set ,最后看下 size 是不是等于 4 <script type="math/tex" id="MathJax-Element-4">4</script>就好了。
  好,我们已经知道了这是一个四边形,再怎么判断它是否是矩形?
  思来想去啊,似乎计算几何中没有简洁的方法,于是思路回到初中数学。你已经知道了这玩意是四边形,那么首先想到的定理就是“三个角是直角的四边形是矩形”。这个就需要把四条线段首尾相连,然后两两判断是否垂直…好像还是有难度。我们从线段的位置关系来入手,如果对于一条线段,其它三条中有一条是平行于它的,另外两条是垂直于它的,这样是不是矩形?
  考虑证明,首先垂直于它的那两条是平行的,然后它又和另外一条平行,那么就是“两组对边分别平行”。初中数学中有结论,这样就是平行四边形。

代码

//计算几何
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <set>
#define eps 1e-8
using namespace std;
struct point{double x, y;}pt[10];
struct vec{point p; double x, y;}v[5];
set<point> s;
vec operator-(point p1, point p2){return (vec){p2,p1.x-p2.x,p1.y-p2.y};}
vec operator-(vec v1, vec v2){return (vec){(point){0,0},v1.x-v2.x,v1.y-v2.y};}
vec operator+(vec v1, vec v2){return (vec){(point){0,0},v2.x+v1.x,v2.y+v1.y};}
double operator*(vec v1, vec v2){return v1.x*v2.y-v2.x*v1.y;}
bool operator<(point p1, point p2){return p1.x==p2.x?p1.y<p2.y:p1.x<p2.x;}
double dc(vec v1, vec v2){return v1.x*v2.x+v1.y*v2.y;}
int main()
{
    int i, T, c1, c2;
    for(scanf("%d",&T);T;T--)
    {
        s.clear();
        for(i=1;i<=8;i++)scanf("%lf%lf",&pt[i].x,&pt[i].y), s.insert(pt[i]);
        if(s.size()!=4){printf("NO\n");continue;}
        for(i=2;i<=8;i+=2)v[i>>1]=pt[i]-pt[i-1];
        c1=c2=0;
        for(i=2;i<=4;i++)
            if(fabs(dc(v[1],v[i]))<eps)c1++;
            else if(fabs(v[1]*v[i])<eps)c2++;
        if(c1==2 and c2==1)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值