【HNOI2011】数矩形

来源:互联网 发布:mac免费的视频播放器 编辑:程序博客网 时间:2024/05/16 11:37

HNOI2011

bzoj2338

最近总是在找些水题做QAQ

说这个题之前,我想先说一些别的事…暑假集训的时候一个叫小兔子的同(神)学(犇)提出的问题:给出一堆点的坐标,求这些点所围成的正方形的个数(可以斜着)。

不得不说当时并没有怎么在意,结果前两天在noip吧里见到有普及组大神用n^3的算法解此题……然后我在回帖里找到了正解…顺便找到了此题……

这大概也是我做的第一个计算几何的题,当时并没有想这么多就开始写了,导致代码很难调所以重新打了一份,还写了个向量的加减之类的…

此题有O(n^2 logn)算法,做法是枚举n个点所构成的所有边O(n^2),然后按第一关键字为中点坐标,第二关键字为边的长度进行排序(O(n^2 logn)),初中生知识可知:中点相同并且长度相等的两条边必然是一个矩形的两条对角线。然后枚举计算即可。

一开始傻X一样double存,各种被误差恶心,然后成功溢出……顺便学会了long double…(scanf(“%Lf”,&a);)在codevs上交总是90分,感觉是精度有问题然后去百度…结果发现中点什么的只需要比较大小为何我要存浮点数(╯‵□′)╯︵┻━┻改成long long…各种恶心的浮点数问题就随之而去了……然后发现自己计算的时候没有计算完全,改了后A了。

第一次打计算几何的代码:

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int size=1510;struct point{    long long x,y;    long long dist()    {        return x*x+y*y;    }}p[size];point operator +(const point &a,const point &b){    return (point){a.x+b.x,a.y+b.y};}point operator -(const point &a,const point &b){    return (point){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;}bool operator !=(const point &a,const point &b){    return (a.x!=b.x)||(a.y!=b.y);}bool operator <(const point &a,const point &b){    if(a.x!=b.x) return a.x<b.x;    return a.y<b.y;}struct edge{    point l,r,mid;    long long len;}l[2250010];bool operator <(const edge &a,const edge &b){    if(a.mid!=b.mid) return a.mid<b.mid;    return a.len<b.len;}int tot=0;int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%lld%lld",&p[i].x,&p[i].y);        for(int j=1;j<i;j++)        {            l[++tot]=(edge){p[i],p[j],(p[i]+p[j]),((p[i]-p[j])).dist()};        }           }//  build(n);    sort(l+1,l+1+tot);/*  for(int i=1;i<=tot;i++)    {        int tot=i;            printf("%lld %lld %lld %lld %lld %lld %lld\n",l[tot].l.x,l[tot].l.y,l[tot].r.x,l[tot].r.y,l[tot].mid.x,l[tot].mid.y,l[tot].len);                }*/    long long ans=0;    for(int i=1,k=1;i<=tot;i++)    {        for(int j=k;j<i;j++)        if(l[i].mid==l[j].mid&&l[i].len==l[j].len)        {            ans=max(ans,(long long) ( sqrt( (l[i].l-l[j].l).dist() ) *sqrt( (long double) (l[i].l-l[j].r).dist() )+0.5) );        //  puts("fuck");        }        else k=i;    }    printf("%lld",ans);    return 0;}/*8-2 3-2 -10 30 -11 -12 1-3 1-2 1*/
0 0
原创粉丝点击