[BZOJ 2338][HNOI 2011]数矩形(计算几何)
2015-02-22 10:54
525 查看
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=2338思路
一个很显然的O(n4)做法是枚举矩形abcd的四个顶点,然后判定矩形是否合法,求出矩形的面积,然后再更新答案O(n^4)做法是枚举矩形abcd的四个顶点,然后判定矩形是否合法,求出矩形的面积,然后再更新答案,这个做法很麻烦,而且很慢,有一个O(n2)的做法,因为矩形的两个对角线相等且相互平分,因此可以O(n2)找出所有的线段,然后O(nlogn)给线段按照线段的中点进行排序,再O(n2)枚举矩形的两条对角线即可更新答案。这里为了避免卡精度,可以避开浮点运算,两点间的距离不开根、求中点时不除以2就行了O(n^2)的做法,因为矩形的两个对角线相等且相互平分,因此可以O(n^2)找出所有的线段,然后O(nlogn)给线段按照线段的中点进行排序,再O(n^2)枚举矩形的两条对角线即可更新答案。这里为了避免卡精度,可以避开浮点运算,两点间的距离不开根、求中点时不除以2就行了代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <cmath> #define MAXN 1520 using namespace std; typedef long long int LL; int n; struct Point { LL x,y; Point(){} Point(LL _x,LL _y) : x(_x),y(_y){} }points[MAXN]; bool operator==(Point a,Point b) { return a.x==b.x&&a.y==b.y; } bool operator<(Point a,Point b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } bool operator>(Point a,Point b) { if(a.x==b.x) return a.y>b.y; return a.x>b.x; } Point operator+(Point a,Point b) { return Point(a.x+b.x,a.y+b.y); } Point operator-(Point a,Point b) { return Point(a.x-b.x,a.y-b.y); } LL operator*(Point a,Point b) { return a.x*b.y-a.y*b.x; } struct Line { int a,b; //线段的两个端点 LL len; Point mid; Line(){} Line(int _a,int _b,LL _len,Point _mid):a(_a),b(_b),len(_len),mid(_mid){} }lines[MAXN*MAXN]; int cnt=0; //对角线总数 LL dist(Point a,Point b) //求点a与点b之间的距离 { return (LL)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } LL max(LL a,int b) { if(a>b) return a; return b; } bool operator==(Line a,Line b) { return a.len==b.len&&a.mid==b.mid; } bool operator<(Line a,Line b) { if(a.len==b.len) return a.mid<b.mid; return a.len<b.len; } int main() { LL ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld%lld",&points[i].x,&points[i].y); for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) lines[++cnt]=Line(i,j,dist(points[i],points[j]),points[i]+points[j]); sort(lines+1,lines+cnt+1); for(int i=1;i<=cnt;i++) for(int j=i-1;j&&lines[i]==lines[j];j--) //为了不重复计算,只数下标小于i的那部分对角线 ans=max(ans,abs((points[lines[i].a]-points[lines[j].a])*(points[lines[i].a]-points[lines[j].b]))); printf("%lld\n",ans); return 0; }
相关文章推荐
- bzoj2338[HNOI2011]数矩形 计算几何
- 【bzoj2338】【HNOI2011】【计算几何】【数矩形】
- bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
- 【计算几何】bzoj2338 [HNOI2011]数矩形
- [BZOJ2338][HNOI2011]数矩形(计算几何)
- 【BZOJ2338】【HNOI2011】数矩形 [计算几何]
- BZOJ 2338 HNOI2011 数矩形 计算几何
- 【bzoj2338】[HNOI2011]数矩形 计算几何
- bzoj 2338: [HNOI2011]数矩形 (计算几何)
- [BZOJ2338][HNOI2011]数矩形(计算几何)
- BZOJ 2338 HNOI 2011 数矩形 计算几何
- 【BZOJ2338】[HNOI2011]数矩形 几何
- BZOJ 2338: [HNOI2011]数矩形
- [BZOJ1185][HNOI2007]最小矩形覆盖(计算几何-旋转卡壳)
- 【bzoj2338】[HNOI2011]数矩形
- [BZOJ2338][HNOI2011]数矩形
- bzoj 2338: [HNOI2011]数矩形
- bzoj1185: [HNOI2007]最小矩形覆盖 计算几何 旋转卡壳
- 2338: [HNOI2011]数矩形 - BZOJ
- bzoj2338: [HNOI2011]数矩形