[BZOJ]2338: [HNOI2011]数矩形 叉积

来源:互联网 发布:百度联盟和淘宝联盟 编辑:程序博客网 时间:2024/05/20 22:30

题解:

n2枚举出两点连成的线段,若两条线段的中点重合且长度相同,那么这四个点可以组成一个矩形。复杂度有点玄学,按理说是可以被卡的。

吐槽:

我原来用通用的求多边形面积方法,多算了一次叉积,竟然TLE了……改了之后快了14s……

代码:

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;#define LL long longconst int maxn=1510;struct point{LL x,y;}p[maxn],a[5];struct line{point p1,p2;LL len;}l[maxn*maxn];LL dis(point p1,point p2){    return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);}bool cmp(line l1,line l2){    if(l1.len!=l2.len)return l1.len<l2.len;    if(l1.p1.x+l1.p2.x!=l2.p1.x+l2.p2.x)return l1.p1.x+l1.p2.x<l2.p1.x+l2.p2.x;    return l1.p1.y+l1.p2.y<l2.p1.y+l2.p2.y;}LL multi(point p1,point p2,point p0){    LL x1,y1,x2,y2;    x1=p1.x-p0.x;y1=p1.y-p0.y;    x2=p2.x-p0.x;y2=p2.y-p0.y;    return x1*y2-x2*y1;}int n,cl=0;LL ans=0;bool check(int x,int y){    if(l[x].len==l[y].len&&(l[x].p1.x+l[x].p2.x==l[y].p1.x+l[y].p2.x)    &&(l[x].p1.y+l[x].p2.y==l[y].p1.y+l[y].p2.y))    return true;return false;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%lld%lld",&p[i].x,&p[i].y);    for(int i=1;i<n;i++)    for(int j=i+1;j<=n;j++)    l[++cl].p1=p[i],l[cl].p2=p[j],l[cl].len=dis(p[i],p[j]);    sort(l+1,l+1+cl,cmp);    for(int i=2;i<=cl;i++)    {        int j=i-1;        while(j&&check(j,i))        {            LL t=abs(multi(l[i].p1,l[i].p2,l[j].p1));            if(t>ans)            {                ans=t;            }            j--;        }    }    printf("%lld",ans);}