数矩形

Time Limit: 20 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  最近某歌手在研究自己的全国巡回演出,他将所有心仪的城市都用平面上一个点来表示,并打算从中挑选出4个城市作为这次巡回演出的地点。
  为了显示自己与众不同,他要求存在一个矩形使得挑选出的4个点恰好是这个矩形的4个顶点,并且希望这个矩形的面积最大。
  这可急坏了经纪人,于是他向全球歌迷征集方案,当然你这位歌迷一定不会错过这个机会。

Input

  第一行是一个正整数N,表示平面上点的个数(即某歌手心仪的城市数)。
  接下来N行,每行是两个整数Xi,Yi,表示对应点的坐标。

Output

  输出一个数,表示最大矩形面积。

Sample Input

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

Sample Output

   10

HINT

  1<=N<=1500 , -10^8<=Xi,Yi<=10^8

Main idea

  给出平面上的若干个点,求出可由这些点作为顶点构成的矩形的最大面积。

Solution

  显然是一道计算几何题。
  先考虑矩形的特征:对角线长度相同并且对角线的中点在同一位置
  然后我们可以n^2枚举出所有对角线的长度并且求出其中点位置,按照长度为第一关键字,中点坐标为第二关键字sort一遍,那么显然可构成矩形的四个点的对角线一定是连续的。
  然后我们枚举所有情况,用矢量叉积来求矩形的面积。
  证明一下复杂度:发现最坏情况应该是所有的中点聚集在同一个点上,以其作为圆心,对角线长度作为直径拓展出成为一个圆,这样的话会有1500/2条长度相同的需要枚举的边,但是由于这是一个圆,所以两点连线不作为直径的构成的边几乎都是不需要枚举的,复杂度正确。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std; const int ONE=; int n;
int cnt,num;
int l[ONE*ONE],r[ONE*ONE];
long long Ans; struct power
{
long long x,y;
}a[ONE]; struct point
{
long long dist;
int i,j;
power mid;
}b[ONE*ONE]; int cmp(const point &a,const point &b)
{
if(a.dist<b.dist) return ;
if(a.dist>b.dist) return ;
if(a.dist==b.dist)
{
if(a.mid.x<b.mid.x) return ;
if(a.mid.y<b.mid.y) return ;
}
return ;
} int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} long long Get_dist(power a,power b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
} long long Get_area(power a1,power a2,power b1,power b2)
{
long long x1=a2.x-a1.x, y1=a2.y-a1.y;
long long x2=b2.x-b1.x, y2=b2.y-b1.y;
return abs( (x1*y2)-(x2*y1) );
} void Deal()
{
for(int k=;k<=num;k++)
{
if(l[k]==r[k]) continue;
for(int i=l[k];i<=r[k];i++)
for(int j=i+;j<=r[k];j++)
{
Ans=max(Ans,Get_area( a[b[i].i],a[b[i].j] , a[b[j].i],a[b[j].j]) );
}
}
} int main()
{
n=get();
for(int i=;i<=n;i++)
{
a[i].x=get(); a[i].y=get();
} for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
b[++cnt].dist=Get_dist(a[i],a[j]);
b[cnt].mid.x=(a[i].x+a[j].x);
b[cnt].mid.y=(a[i].y+a[j].y);
b[cnt].i=i; b[cnt].j=j;
} sort(b+,b+cnt+,cmp); int i=; while(i<=cnt)
{
i++;
l[++num]=i;
while(b[i].dist==b[i+].dist && b[i].mid.x==b[i+].mid.x && b[i].mid.y==b[i+].mid.y && i<=cnt)
{
i++;
}
r[num]=i;
} Deal();
printf("%lld",Ans/); }

【BZOJ2338】【HNOI2011】数矩形 [计算几何]的更多相关文章

  1. bzoj2338[HNOI2011]数矩形 计算几何

    2338: [HNOI2011]数矩形 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1535  Solved: 693[Submit][Status ...

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

    题目链接: 2338: [HNOI2011]数矩形 Time Limit: 20 Sec  Memory Limit: 128 MB Description Input   Output 题意: 思路 ...

  3. 【bzoj2338】[HNOI2011]数矩形 计算几何

    题目描述 题解 计算几何 由于对角线平分且相等的四边形是矩形,因此我们可以把每条对角线存起来,按照对角线长度和中点位置为关键字排序,这样对于每个相同长度和中点的对角线就排到了一起. 于是对于每段可能形 ...

  4. 【计算几何】bzoj2338 [HNOI2011]数矩形

    对于两条线段,若其中点重合,且长度相等,那么它们一定是某个矩形的对角线. N*N地处理出所有线段,排序,对每一部分中点重合.长度相等的线段进行暴力枚举,更新答案. 用 long double 注意EP ...

  5. BZOJ2338: [HNOI2011]数矩形

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2338 中学数学老师告诉我们,一个矩形的两条对角线相等,所以只要把所有的边拿出来,记录下中点坐标 ...

  6. BZOJ 2338 HNOI2011 数矩形 计算几何

    题目大意:给定n个点,求一个最大的矩形,该矩形的四个顶点在给定的点上 找矩形的方法是记录全部线段 若两条线段长度相等且中点重合 这两条线段就能够成为矩形的对角线 于是我们找到全部n*(n-1)/2条线 ...

  7. {bzoj2338 [HNOI2011]数矩形 && NBUT 1453 LeBlanc}平面内找最大矩形

    思路: 枚举3个点,计算第4个点并判断是否存在,复杂度为O(N3logN)或O(N3α) 考虑矩形的对角线,两条对角线可以构成一个矩形,它们的长度和中点必须完全一样,于是将所有线段按长度和中点排序,那 ...

  8. 【BZOJ2338】[HNOI2011]数矩形 几何

    [BZOJ2338][HNOI2011]数矩形 题解:比较直观的做法就是枚举对角线,两个对角线能构成矩形当且仅当它们的长度和中点相同,然后用到结论:n个点构成的矩形不超过n^2.5个(不会证),所以两 ...

  9. 【题解】Luogu P3217 [HNOI2011]数矩形

    原题链接:P3217 [HNOI2011]数矩形 什么??!怎么又是计算几何,您钛毒瘤了-- 这道题真的是毒瘤 凸包?旋转卡壳? 看一下数据,N<=1500? 暴力 没错,就是暴力,N^2没毛病 ...

随机推荐

  1. 四大IO抽象类

     四大IO抽象类   InputStream/OutputStream和Reader/writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用.然后,通过它们具体的子类熟悉相 ...

  2. HBase全网最佳学习资料汇总

    HBase全网最佳学习资料汇总 摘要: HBase这几年在国内使用的越来越广泛,在一定规模的企业中几乎是必备存储引擎,互联网企业阿里巴巴.百度.腾讯.京东.小米都有数千台的HBase集群,中国电信的话 ...

  3. 问题:docker pull 用户登陆tricky,Error response from daemon: unauthorized: incorrect username or password

    问题描述: PS C:\WINDOWS\system32> docker pull rabbitmqUsing default tag: latest Please login prior to ...

  4. Linux中java应用程序的部署,使其开机自动启动

    初步需求:将在Windows/MyEclipse中开发的java应用程序部署到Linux服务器上,使其运行 针对需求,可以参考下面这些文章,但是这些文章很多东西没有提及到,我自己尝试部署运行 在lin ...

  5. LINQ学习笔记——(3)基本查询操作符

    Select() 作用于uIEnumerable<TSource>类型 public static void Test() { List<string> persons = n ...

  6. linux消息队列通信

    IPC机制 进程间通信机制(Inter Process Communication,IPC),这些IPC机制的存在使UNIX在进程通信领域手段相当丰富,也使得程序员在开发一个由多个进程协作的任务组成的 ...

  7. VFS dup ,dup2

    Linux支持各种各样的文件系统格式,如ext2.ext3.reiserfs.FAT.NTFS.iso9660等等,不同的磁盘分区.光盘或其它存储设备都有不同的文件系统格式,然而这些文件系统都可以mo ...

  8. 创建带maven的javaWeb项目

    1File——Maven——maven-archtypes-webapp GroupId:表示项目组织唯一标识符 ArtifacrId:表示项目唯一标识符 例如项目名称 Version是项目版本 这三 ...

  9. PAT 1089 狼人杀-简单版

    https://pintia.cn/problem-sets/994805260223102976/problems/1038429385296453632 以下文字摘自<灵机一动·好玩的数学& ...

  10. 并发(一) Semaphore

    Semaphore 控制对资源的并发访问数,构造时如果传参为1,则近似于ReentrantLock,差别在于锁的释放.可以一个线程获取锁,另外一个线程释放锁,在一些死锁处理的场合比较适用. 如上所示, ...