bzoj 2338: [HNOI2011]数矩形 (计算几何)

本文介绍了一种求解顶点限定的最大矩形问题的算法实现。通过预处理点集并利用几何计算方法,该算法有效地寻找由点集构成的最大面积矩形。代码中运用了C++语言进行具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

传送门

题目大意:给出n个点,求顶点都在n个点中的最大矩形。

题解

代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define N 1503
#define LL long long 
using namespace std;
int n,cnt,top,st[N*N];
struct data{
    LL x,y;
    data(LL X=0,LL Y=0) {
        x=X,y=Y;
    }
}p[N]; 
data operator -(data a,data b){
    return data(a.x-b.x,a.y-b.y);
}
LL pow(LL x){
    return x*x;
}
struct line{
    LL x,y; LL len;
    double ang; int a,b;
    line(int A=0,int B=0) {
        a=A,b=B; x=p[a].x+p[b].x; y=p[a].y+p[b].y;
        len=pow(p[a].x-p[b].x)+pow(p[a].y-p[b].y);
        ang=atan2(p[b].y-p[a].y,p[b].x-p[a].x);
    }
}l[N*N];
int cmp(line a,line b){
    return a.x<b.x||a.x==b.x&&a.y<b.y||a.x==b.x&&a.y==b.y&&a.len<b.len||
           a.x==b.x&&a.y==b.y&&a.len==b.len&&a.ang<b.ang;   
}
bool check(line a,line b)
{
   return a.x==b.x&&a.y==b.y&&a.len==b.len;
}
LL cross(data a,data b){
    return a.x*b.y-a.y*b.x;
}
LL squ(line i,line j)
{
    data v=p[i.a]-p[j.a];
    data u=p[i.b]-p[j.a];
    return abs(cross(v,u));
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld%lld",&p[i].x,&p[i].y);
    cnt=0;
    for (int i=1;i<=n;i++)
     for (int j=i+1;j<=n;j++)
      l[++cnt]=line(i,j);
    sort(l+1,l+cnt+1,cmp);
    LL ans=0;
    for (int i=1,j;i<=cnt;i=j+1) {
        j=i;
        top=0;
        while (j<=cnt&&check(l[i],l[j])) {
            st[++top]=j;
            j++;
        }
        j--;
        int tail=1;
        for (int k=1;k<=top;k++) {
            int c=tail;
            while (squ(l[st[tail]],l[st[k]])<squ(l[st[tail%top+1]],l[st[k]])){
                tail=tail%top+1;
                if (tail==c) break;
            }
            ans=max(ans,squ(l[st[tail]],l[st[k]]));
        }
    }
    printf("%lld\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值