数矩形

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. Windows扩展屏开发总结

    本文来自网易云社区 作者:梁敏 一.多屏设置 在设置-系统-可以点击显示器1和2,可以进行单独设置: "使之成为我的主显示器"可以设置当前显示器是主屏:主屏的选择会决定整个虚拟屏幕 ...

  2. Borland和Micorsoft的对话(转载自月光软件网)

      Borland与Microsoft关于Delphi的对话 Bear 1.Delphi较贵  一套Delphi的价格大约相当于两套Visual Studio  ------------------- ...

  3. CSP201509-1:数组分段

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的“计算机职业资格认证”考试,针对计算机软件开发. ...

  4. NLP系列-中文分词(基于词典)

    中文分词概述 词是最小的能够独立活动的有意义的语言成分,一般分词是自然语言处理的第一项核心技术.英文中每个句子都将词用空格或标点符号分隔开来,而在中文中很难对词的边界进行界定,难以将词划分出来.在汉语 ...

  5. URAL 1732 Ministry of Truth(KMP)

    Description In whiteblack on blackwhite is written the utterance that has been censored by the Minis ...

  6. centos7 centos6中 更改默认的系统启动级别

    centos6中更改默认的启动级别 方法: 1.vi /etc/inittab 2.找到id:x:initdefault:,我的系统是id:3:initdefault:,即默认以字符模式启动. 3.将 ...

  7. PokeCats开发者日志(一)

      现在是PokeCats游戏开发的第三天的上午,突然心血来潮想记录一下这个开发过程,于是写起了开发者日志. day1   作为一只ACM退役喵,寒假回家,闲着没事,天天在召唤师峡谷里闲逛也挺没意思的 ...

  8. 获取JavaScript对象的方法

    写定义一个对象,如var a = new Array(),debugger,然后执行F12控制台的开发者模式下,进入断点,断点里面 会显示所有的方法的. var a = new Array(); de ...

  9. java线程(1)——三种创建线程的方式

    前言 线程,英文Thread.在java中,创建线程的方式有三种: 1.Thread 2.Runnable 3.Callable 在详细介绍下这几种方式之前,我们先来看下Thread类和Runnabl ...

  10. DataView RowFilter Syntax [C#]

    RowFilter语法 private void btnEnquiry_Click(object sender, EventArgs e) { string filterExpression = st ...