【BZOJ】【1069】【SCOI2007】最大土地面积
2015-05-13 17:31
260 查看
计算几何/旋转卡壳
从已知点中选出四个使得选出的四边形面积最大,很明显我们应该在凸包上搞。我一开始的思路是:枚举 i ,找到 i 的对锺点cur1,这两个点将凸包分成了两半,我们在左半中枚举一个 j ,然后在右半中找一个离 j 最远的“对锺点”(可能不是?反正找的是最远……)cur2,然后求cur1和cur2都是单调的,复杂度为枚举 i, j的$O(n^2)$
然而跪了= =然后我去Orz了proverbs的题解,得到启示:我们可以枚举一条对角线,然后在左半和右半中各找一条跟这条对角线最远的点!这两个点的寻找明显是单调的,复杂度为枚举对角线的两个端点的$O(n^2)$
Orzzzzz思路还是不够开阔啊
一开始错我还以为是旋转卡壳写错了……后来发现原来是凸包写错了QAQ
/************************************************************** Problem: 1069 User: Tunix Language: C++ Result: Accepted Time:284 ms Memory:1340 kb ****************************************************************/ //BZOJ 1069 #include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define rep(i,n) for(int i=0;i<n;++i) #define F(i,j,n) for(int i=j;i<=n;++i) #define D(i,j,n) for(int i=j;i>=n;--i) #define pb push_back using namespace std; typedef long long LL; inline int getint(){ int r=1,v=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; return r*v; } const int N=2010; /*******************template********************/ struct Poi{ double x,y; Poi(){} Poi(double x,double y):x(x),y(y){} void read(){scanf("%lf%lf",&x,&y);} }p ,ch ; typedef Poi Vec; Vec operator - (const Poi &a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);} bool operator < (const Poi &a,const Poi &b){return a.x<b.x || (a.x==b.x && a.y<b.y);} inline double Dot(const Poi &a,const Poi &b){return a.x*b.x+a.y*b.y;} inline double Cross(const Poi &a,const Poi &b){return a.x*b.y-a.y*b.x;} int n,m; double ans; void graham(Poi *p,int n){ sort(p+1,p+n+1); ch[++m]=p[1]; F(i,2,n){ while(m>1 && Cross(ch[m]-ch[m-1],p[i]-ch[m-1])<=0) m--; ch[++m]=p[i]; } int k=m; D(i,n-1,1){ while(m>k && Cross(ch[m]-ch[m-1],p[i]-ch[m-1])<=0) m--; ch[++m]=p[i]; } if (n>1) m--; } double getans(Poi a1,Poi a2,Poi b1,Poi b2){ return Cross(a2-a1,b1-a1)+Cross(b2-b1,a1-b1); } void rot(Poi *p,int n){ int cur1=2,cur2,j; F(i,1,n) p[i+n]=p[i]; F(i,1,n-1){ cur1=i+1; j=cur1+1; cur2=j+1; for(;j<i+n-1;j++){ while(Cross(p[cur1+1]-p[i],p[j]-p[i]) > Cross(p[cur1]-p[i],p[j]-p[i])) cur1=cur1%n+1; while(Cross(p[cur2+1]-p[j],p[i]-p[j]) > Cross(p[cur2]-p[j],p[i]-p[j])){ cur2=cur2%n+1; if (cur2>=i+n-1) break; } if (cur2>i+n-1) break; ans=max(ans,getans(p[i],p[cur1],p[j],p[cur2])); } } } int main(){ #ifndef ONLINE_JUDGE freopen("1069.in","r",stdin); // freopen("1069.out","w",stdout); #endif n=getint(); F(i,1,n) p[i].read(); graham(p,n); rot(ch,m); printf("%.3f\n",ans*0.5); return 0; }
View Code
1069: [SCOI2007]最大土地面积
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1853 Solved: 683
[Submit][Status][Discuss]
Description
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。Input
第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。Output
最大的多边形面积,答案精确到小数点后3位。Sample Input
50 0
1 0
1 1
0 1
0.5 0.5
Sample Output
1.000HINT
数据范围 n<=2000, |x|,|y|<=100000Source
[Submit][Status][Discuss]相关文章推荐
- bzoj 1069 [SCOI2007]最大土地面积(旋转卡壳)
- BZOJ-1069 [SCOI2007]最大土地面积
- BZOJ 1069 [SCOI2007]最大土地面积 旋转卡壳
- BZOJ1069 [SCOI2007]最大土地面积
- [BZOJ1069][SCOI2007]最大土地面积
- bzoj1069【SCOI2007】最大土地面积
- [Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)
- bzoj 1069: [SCOI2007]最大土地面积(旋转卡壳)
- BZOJ 1069 [SCOI2007]最大土地面积 ——计算几何
- 【旋转卡壳】【bzoj 1069】: [SCOI2007]最大土地面积
- BZOJ 1069: [SCOI2007]最大土地面积 [旋转卡壳]
- bzoj1069 [SCOI2007]最大土地面积 旋转卡壳
- ●BZOJ 1069 [SCOI2007]最大土地面积
- bzoj 1069: [SCOI2007]最大土地面积 (旋转卡壳)
- BZOJ1069: [SCOI2007]最大土地面积
- bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳
- BZOJ 1069 [SCOI2007]最大土地面积 旋转卡壳
- bzoj1069: [SCOI2007]最大土地面积
- 【BZOJ 1069】 [SCOI2007]最大土地面积
- [省选前题目整理][BZOJ 1069][SCOI 2007]最大土地面积(旋转卡壳)