Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 8437 | Accepted: 2497 |
Description
Input
Output
Sample Input
3 3 4 2 6 2 7 5 2 6 3 9 2 0 8 0 6 5 -1
Sample Output
0.50 27.00
Source
旋转卡壳求凸包上的最大三角形面积。
只要把旋转卡壳变形一下:
之前的旋转卡壳是求一个点及其相邻点的对踵点,现在求一个点的时候枚举其他每一个点和这个点的对踵点即可。
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #define eps 1e-9 using namespace std; struct Point { double x,y; }a[50005]; int n,tail,h[50005]; bool cmp(Point a,Point b) { if (a.x==b.x) return a.y<b.y; return a.x<b.x; } double Cross(Point a,Point b,Point c) { return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } void Graham() { sort(a+1,a+1+n,cmp); tail=0; for (int i=1;i<=n;i++) { while (tail>=2&&Cross(a[h[tail-2]],a[h[tail-1]],a[i])<eps) tail--; h[tail++]=i; } int tmp=tail; h[tail++]=n-1; for (int i=n-2;i;i--) { while (tail>tmp&&Cross(a[h[tail-2]],a[h[tail-1]],a[i])<eps) tail--; h[tail++]=i; } tail--; } double Rotating_calipers() { double ans=0.0; for (int i=0;i<tail;i++) { int x=i+1; for (int j=i+1;j<=tail;j++) { while (fabs(Cross(a[h[i]],a[h[j]],a[h[x+1]]))>fabs(Cross(a[h[i]],a[h[j]],a[h[x]]))) x=(x+1)%tail; ans=max(ans,fabs(Cross(a[h[i]],a[h[j]],a[h[x]]))); } } return ans/2.000; } int main() { while (scanf("%d",&n)!=EOF) { if (n==-1) break; for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); Graham(); printf("%.2lf\n",Rotating_calipers()); } return 0; }
原文地址:http://blog.csdn.net/regina8023/article/details/43899535