【bzoj2338】[HNOI2011]数矩形

Description

这里写图片描述

题解

通过这些点我们可以得到很多线段对吧。
两个线段如果作为矩形的对角线,这就要求它们长度相等且互相平分。
互相平分也就是中点重合。
我们把这些线段按照长度为第一关键字,中点位置为第二关键字排序,这样能够构成矩形的线段一定就在一起了,在对于每个线段向前暴力找可以与它构成矩形的线段。这样就OK了。
注意全程用long long而且中点不除以二,距离不开根号,面积用叉乘。这样才能保证精度。
千万别用double啥的。

#include<bits/stdc++.h>
using namespace std;

const int N = 1500 + 10;

typedef long long ll;

struct Point{
    ll x, y;
    Point(){};
    Point(ll a, ll b){x = a, y = b;}
    bool operator == (const Point &a) const{
        return a.x == x && a.y == y;
    }
    ll operator * (const Point &a) const{
        return x * a.y - y * a.x;
    }
    Point operator - (const Point &a) const{
        return Point(x - a.x, y - a.y);
    }
    Point operator + (const Point &a) const{
        return Point(x + a.x, y + a.y);
    }
}pt[N];
struct Line{
    ll len;
    Point p1, p2, mdp;
    bool operator < (const Line &a) const{
        if(len == a.len)
            return (mdp.x < a.mdp.x) || (mdp.x == a.mdp.x && mdp.y < a.mdp.y);
        else return len < a.len;
    }
}ln[N*N>>1];
int n, tot;

ll sqr(ll x){return x * x;}
ll dist(Point a, Point b){
    return sqr(a.x - b.x) + sqr(a.y - b.y);
}
ll labs(ll x){return x > 0 ? x : -x;}

void init(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%lld%lld", &pt[i].x, &pt[i].y);
        for(int j = 1; j < i; j++){
            ln[++tot].p1 = pt[i];
            ln[tot].p2 = pt[j];
            ln[tot].len = dist(pt[i], pt[j]);
            ln[tot].mdp = pt[i] + pt[j];
        }
    }
}

void work(){
    ll ans = 0, s;
    sort(ln+1, ln+tot+1);
    for(int i = 1; i <= tot; i++)
    for(int j = i-1; ln[i].mdp == ln[j].mdp && ln[i].len == ln[j].len && j; j--){
        s = labs((ln[j].p1 - ln[i].p1) * (ln[j].p2 - ln[i].p1));
        if(s > ans) ans = s;
    }
    printf("%lld\n", ans);
}

int main(){
    init();
    work();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值