列表

详情


NC20091. [HNOI2011]数矩形

描述

最近某歌手在研究自己的全球巡回演出计划,他将所有心仪的城市都用平面上的一个点来表示,并打算从中挑选出 4 个城市作为这次巡回演出的地点。

为了显示自己与众不同,他要求存在一个矩形使得挑选出的 4 个点恰好是这个矩形的 4 个顶点,并且希望这个矩形的面积最大。

这可急坏了其经纪人,于是他向全球歌迷征集方案,当然你这位歌迷一定不会错过这个机会。

输入描述

从文件input.txt中读入数据,输入文件的第一行是一个正整数N,表示平面上点的个数(即某歌手心仪的城市数)。
接下来的N行,每行是由空格隔开的两个整数Xi和Yi,表示其对应点的坐标。
20%的数据满足N≤500,100%的数据满足N≤1500,1−108≤Xi,Yi≤108,且输入数据保证答案存在。

输出描述

输出文件 output.txt 仅包含一个非负整数,表示最大的矩形面积。

示例1

输入:

8
-2 3
-2 -1
0 3
0 -1
1 -1
2 1 
-3 1 
-2 1

输出:

10

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 321ms, 内存消耗: 29688K, 提交时间: 2019-03-16 10:41:07

#include<bits/stdc++.h>
#define ll long long
using namespace std;
void qmax(ll &x,ll y) {if (x<y) x=y;}
void qmin(ll &x,ll y) {if (x>y) x=y;}
inline int read()
{
    char s;
    int k=0,base=1;
    while((s=getchar())!='-'&&s!=EOF&&!(isdigit(s)));
    if(s==EOF)exit(0);
    if(s=='-')base=-1,s=getchar();
    while(isdigit(s)) {k=k*10+(s^'0');s=getchar();}
    return k*base;
}
inline void write(int x)
{
    static char cnt,num[15];cnt=0;
    if (!x)
    {
        putchar('0');
        return;
    }
    for (;x;x/=10) num[++cnt]=x%10;
    for (;cnt;putchar(num[cnt--]+48));
}
const int maxn=1550;
const int maxm=1500*(1500-1)/2+5;
int n,id,sum;
struct node
{
    int x,y;
} a[maxn];
struct node1
{
    int a,b;
    node mid;
    ll dis;
} b[maxm];
int r[maxm];
ll ans;
ll dis(node aa,node bb)
{//求两点之间的距离
    return (ll)(aa.x-bb.x)*(aa.x-bb.x)+(ll)(aa.y-bb.y)*(aa.y-bb.y);
}
ll qs(node a1,node a2,node b1,node b2)//求矩形面积,a1,a2在一条对角线上
{
    ll s1=max(abs(a1.x-a2.x),abs(b1.x-b2.x));
    s1=s1*(ll)max(abs(a1.y-a2.y),abs(b1.y-b2.y));
    s1=s1-(ll)abs(a1.x-b1.x)*abs(a1.y-b1.y);
    s1=s1-(ll)abs(a2.x-b1.x)*abs(a2.y-b1.y);
    return s1;
}
bool cmp(node1 aa,node1 bb)
{
    if (aa.dis!=bb.dis) return aa.dis>bb.dis;
    if (aa.mid.x!=bb.mid.x) return aa.mid.x<bb.mid.x;
    return aa.mid.y<bb.mid.y;
}
int main()
{
#ifdef ylx
    freopen("p3217.in","r",stdin);
    freopen("p3217.out","w",stdout);
#endif
    n=read();
    for (int i=1;i<=n;i++)
    {
        a[i].x=read();a[i].y=read();
    }
    for (int i=1;i<=n;i++)
        for (int j=i+1;j<=n;j++)
        {
            ++id;
            b[id].a=i,b[id].b=j;
            b[id].mid.x=a[i].x+a[j].x;
            b[id].mid.y=a[i].y+a[j].y;//避免精度误差所以没有/2
            b[id].dis=dis(a[i],a[j]);
        }
    sort(b+1,b+id+1,cmp);
    sum=1;
    for (int i=1;i<=id;)
    {//不同种的分开
        while (i==1||(b[i].dis==b[i-1].dis&&b[i].mid.x==b[i-1].mid.x&&b[i].mid.y==b[i-1].mid.y)) i++;
        r[sum]=i-1;i++;
        sum++;
    }
    for (int j=1;j<=sum;j++)
    {//枚举
        for (int i=r[j-1]+1;i<r[j];i++)
            for (int k=i+1;k<=r[j];k++)
            {
                qmax(ans,qs(a[b[i].a],a[b[i].b],a[b[k].a],a[b[k].b]));
            }
    }
    printf("%lld\n",ans);
    return 0;
}

上一题