[BZOJ]2338: [HNOI2011]数矩形 叉积

题解:

n2 枚举出两点连成的线段,若两条线段的中点重合且长度相同,那么这四个点可以组成一个矩形。复杂度有点玄学,按理说是可以被卡的。

吐槽:

我原来用通用的求多边形面积方法,多算了一次叉积,竟然TLE了……改了之后快了14s……

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn=1510;
struct point{LL x,y;}p[maxn],a[5];
struct line{point p1,p2;LL len;}l[maxn*maxn];
LL dis(point p1,point p2)
{
    return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
bool cmp(line l1,line l2)
{
    if(l1.len!=l2.len)return l1.len<l2.len;
    if(l1.p1.x+l1.p2.x!=l2.p1.x+l2.p2.x)return l1.p1.x+l1.p2.x<l2.p1.x+l2.p2.x;
    return l1.p1.y+l1.p2.y<l2.p1.y+l2.p2.y;
}
LL multi(point p1,point p2,point p0)
{
    LL x1,y1,x2,y2;
    x1=p1.x-p0.x;y1=p1.y-p0.y;
    x2=p2.x-p0.x;y2=p2.y-p0.y;
    return x1*y2-x2*y1;
}
int n,cl=0;
LL ans=0;
bool check(int x,int y)
{
    if(l[x].len==l[y].len&&(l[x].p1.x+l[x].p2.x==l[y].p1.x+l[y].p2.x)
    &&(l[x].p1.y+l[x].p2.y==l[y].p1.y+l[y].p2.y))
    return true;return false;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld%lld",&p[i].x,&p[i].y);
    for(int i=1;i<n;i++)
    for(int j=i+1;j<=n;j++)
    l[++cl].p1=p[i],l[cl].p2=p[j],l[cl].len=dis(p[i],p[j]);
    sort(l+1,l+1+cl,cmp);
    for(int i=2;i<=cl;i++)
    {
        int j=i-1;
        while(j&&check(j,i))
        {
            LL t=abs(multi(l[i].p1,l[i].p2,l[j].p1));
            if(t>ans)
            {
                ans=t;
            }
            j--;
        }
    }
    printf("%lld",ans);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值