BZOJ2338: [HNOI2011]数矩形

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2338

中学数学老师告诉我们,一个矩形的两条对角线相等,所以只要把所有的边拿出来,记录下中点坐标及长度,然后排一遍序扫一遍更新答案。。(听说开double会炸?

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 1505
#define inf int(1e9)
#define eps 1e-6
using namespace std;
typedef long long ll;
struct data{ll len,x,y;int a,b;
}a[maxn*maxn];
struct node{ll x,y;
};
int n,cnt,next,now;
ll ans,x[maxn],y[maxn];
ll read(){
    ll x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
ll sqr(ll x){
    return x*x;
}
ll dis(int a,int b){
    return sqr(x[a]-x[b])+sqr(y[a]-y[b]);
}
bool cmp(data a,data b){
    if (a.x==b.x&&a.len==b.len) return a.y<b.y;
    else if (a.len==b.len) return a.x<b.x;
    return a.len<b.len;
}
bool jud(data a,data b){
    if (a.x==b.x&&a.y==b.y&&a.len==b.len) return 1;
    return 0;
}
ll cross(node p,node q){
    return abs(p.x*q.y-p.y*q.x); 
}
void solve(data a,data b){
    node p=(node){x[a.a]-x[a.b],y[a.a]-y[a.b]};
    node q=(node){x[a.a]-x[b.a],y[a.a]-y[b.a]};
    ans=max(ans,cross(p,q));
}
int main(){
    scanf("%d",&n);
    rep(i,1,n){
        x[i]=read(); y[i]=read();
    }
    rep(i,1,n) rep(j,i+1,n) a[++cnt]=(data){dis(i,j),x[i]+x[j],y[i]+y[j],i,j};
    sort(a+1,a+1+cnt,cmp);  
    now=cnt;
    while (now>1){
        next=now-1;
        while (jud(a[now],a[next])) {
            solve(a[now],a[next]);
            next--;
        }
        now--;
    }   
    printf("%lld\n",ans);
    return 0;
}

 

posted on 2015-12-05 22:42  ctlchild  阅读(154)  评论(0编辑  收藏  举报

导航