bzoj2338数矩形(rectangle)

数矩形(rectangle)


计算几何

把所有点两两连线,把这些线按长度排序,再按中点排序

能组成矩形的线一定是连续的

最坏就是所有点围成一个圆,交于圆心

复杂度O(可以过)

要用叉积,不然会被卡精

我居然认为极角序就是逆时针,错了好久

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 1505
#define eps 1e-11
using namespace std;
int n,tot;
struct po{
    long long x,y,len,mx,my;
}s[maxn],a[maxn*maxn],t1,t2;
long long ans;
long long getl(int i,int j){
    return (s[i].x-s[j].x)*(s[i].x-s[j].x)+(s[i].y-s[j].y)*(s[i].y-s[j].y);
}
bool cmp(po a,po b){
    if(a.len==b.len)return a.mx<b.mx||a.mx==b.mx&&a.my<b.my;
    return a.len<b.len;
}
long long cj(po a,po b){
    return a.x*b.y-a.y*b.x;
}
bool pd(int i,int j)
{
    if(getl(a[i].x,a[j].x)!=getl(a[i].y,a[j].y))return 0;
    if(getl(a[i].x,a[j].y)!=getl(a[i].y,a[j].x))return 0;
    return 1;
}
long long size(int i,int j){
    po h[4];
    h[0]=s[a[i].x],h[1]=s[a[j].y];
    h[2]=s[a[i].y],h[3]=s[a[j].x]; 
    long long sum=0;
    for(int i=0;i<4;i++){
        sum+=cj(h[i],h[(i+1)%4]); 
    }
    return abs(sum);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%lld%lld",&s[i].x,&s[i].y);
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            a[++tot].x=i,a[tot].y=j;
            a[tot].mx=s[i].x+s[j].x,a[tot].my=s[i].y+s[j].y;
            a[tot].len=getl(i,j);
        }
    }
    sort(a+1,a+tot+1,cmp);
    int l=1,now=1;
    while(l<=tot){
        while(a[l].len==a[now].len&&a[now].mx==a[l].mx&&a[now].my==a[l].my&&now<=tot)now++;
        now--;
        for(int i=l;i<=now;i++){
            for(int j=i+1;j<=now;j++){
                if(pd(i,j)){
                    ans=max(ans,size(i,j));
                }
            }
        }
        now++;l=now;
    }
    cout<<(long long)ans/2<<endl;
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值