【bzoj2338】[HNOI2011]数矩形

来源:互联网 发布:美食拍照软件 编辑:程序博客网 时间:2024/06/06 00:04

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
原创粉丝点击