【BZOJ2338】[HNOI2011]数矩形 几何

【BZOJ2338】[HNOI2011]数矩形

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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int n,tot;
ll ans;
int x[1510],y[1510];
struct node
{
	ll len;
	int x,y,a,b;
}p[2000000];
bool cmp(node a,node b)
{
	return (a.len==b.len)?((a.x==b.x)?(a.y<b.y):(a.x<b.x)):(a.len<b.len);
}
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
ll chaji(ll x1,ll y1,ll x2,ll y2)
{
	return x1*y2-x2*y1;
}
ll sqr(int a,int b,int c)
{
	return abs(chaji(x[b]-x[a],y[b]-y[a],x[c]-x[a],y[c]-y[a]));
}
int main()
{
	n=rd();
	int i,j,last,k;
	for(i=1;i<=n;i++)	x[i]=rd(),y[i]=rd();
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)
		{
			p[++tot].len=(ll)(x[i]-x[j])*(x[i]-x[j])+(ll)(y[i]-y[j])*(y[i]-y[j]);
			p[tot].x=x[i]+x[j],p[tot].y=y[i]+y[j],p[tot].a=i,p[tot].b=j;
		}
	}
	sort(p+1,p+tot+1,cmp);
	for(i=1;i<=tot;i++)
	{
		if(p[i].len!=p[i-1].len||p[i].x!=p[i-1].x||p[i].y!=p[i-1].y)
		{
			for(last=i;last<=tot&&p[last].len==p[i].len&&p[last].x==p[i].x&&p[last].y==p[i].y;last++);
			for(j=i;j<last;j++)	for(k=j+1;k<last;k++)	ans=max(ans,sqr(p[k].a,p[j].a,p[j].b));
		}
	}
	printf("%lld",ans);
	return 0;
}//8 -2 3 -2 -1 0 3 0 -1 1 -1 2 1 -3 1 -2 1
时间: 2024-08-02 22:06:03

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

BZOJ2338: [HNOI2011]数矩形

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2338 中学数学老师告诉我们,一个矩形的两条对角线相等,所以只要把所有的边拿出来,记录下中点坐标及长度,然后排一遍序扫一遍更新答案..(听说开double会炸? #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #include<iostream> #i

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

对于两条线段,若其中点重合,且长度相等,那么它们一定是某个矩形的对角线. N*N地处理出所有线段,排序,对每一部分中点重合.长度相等的线段进行暴力枚举,更新答案. 用 long double 注意EPS的设置,卡精度. 注意数组大小的设置,容易MLE. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<iostream> 5 using namespace std; 6

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

题目链接: 2338: [HNOI2011]数矩形 Time Limit: 20 Sec  Memory Limit: 128 MB Description Input Output 题意: 思路: 求最大的矩形面积,先把这些点转化成线段,记录下线段的长度和中点和两个端点,形成矩形说明对角线长度相等,且共中点,所以把线段按长度和中点排序,如果都相等,然后用三角形的三个顶点坐标计算面积的公式计算最大面积就好了; AC代码: /************************************

BZOJ 2338 HNOI2011 数矩形 计算几何

题目大意:给定n个点,求一个最大的矩形,该矩形的四个顶点在给定的点上 找矩形的方法是记录所有线段 若两条线段长度相等且中点重合 这两条线段就可以成为矩形的对角线 于是我们找到所有n*(n-1)/2条线段,按长度排序,长度相等按照中点排序,然后对于每个点向前找符合要求的,计算面积,更新ans 注意避免一切double!长度切记不能开根号,直接用long long存储,否则第三个点有两条长度极其接近的线段把double卡掉,计算面积要用叉积,中点不要除以2,连math库都不用开了! #include

数矩形(N - 暴力求解、打表)

数矩形 Description 给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形,下图为高为2,宽为4的网格. Input 第一行输入一个t, 表示有t组数据,然后每行输入n,m,分别表示网格的高和宽 ( n < 100 , m < 100). Output 每行输出网格中有多少个矩形. Sample Input 2 1 2 2 4 Sample Output 3 30 题意: 一个N*M的网格,计算有多少矩形? 分析: 数学问题. 用到暴力,和打表的方法.打表就是找规律然后直接

bzoj2338 数矩形

给出N(N≤1500)个点,求选四个点作为顶点组成矩形的最大面积,保证有解. 对每两个点连边,按边长排序,枚举等长且中点相同的边作为对角线组成矩形,计算面积取最大值. 时间复杂度O(n2logn) #include<cstdio> #include<algorithm> int xs[1600],ys[1600]; long long ans=0; struct edge{ int x1,y1,x2,y2; long long len; int xm,ym; void cal(){

平行四边形数(fzoj_2231) 几何

 Problem 2231 平行四边形数 Accept: 44    Submit: 124 Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description 在一个平面内给定n个点,任意三个点不在同一条直线上,用这些点可以构成多少个平行四边形?一个点可以同时属于多个平行四边形.  Input 多组数据(<=10),处理到EOF. 每组数据第一行一个整数n(4<=n<=500).接下来n行每行两个整数xi,yi(0

BZOJ 2338 HNOI 2011 数矩形 计算几何

题目大意:给出平面上的一些点,求这些点中组成的矩形的最大面积. 思路:任意找四个点然后判断肯定是不行的,那么我们不妨来想一想矩形的性质.比如,对角线的交点是两条对角线的中点,对角线相等.这样的话只要找到一对线段,使得他们的中点相同,并且长度相同,那么这两个对角线一定能够组成一个矩形.只有就可以利用叉积求出面积了. 比较坑的一点是,这个题万万不能用double,因为有一个点专门卡double.可以尝试用long double,最好还是避免精度问题,统一用整数. CODE: #include <cs

学科-几何:分形几何学

ylbtech-学科-几何:分形几何学 分形几何学是一门以不规则几何形态为研究对象的几何学.相对于传统几何学的研究对象为整数维数,如,零维的点.一维的线.二维的面.三维的立体乃至四维的时空.分形几何学的研究对象为非负实数维数,如0.63.1.58.2.72.log2/log3(参见康托尔集).因为它的研究对象普遍存在于自然界中,因此分形几何学又被称为“大自然的几何学”. 一个数学意义上分形的生成是基于一个不断迭代的方程式,即一种基于递归的反馈系统.分形有几种类型,可以分别依据表现出的精确自相似性