poj 3348(求凸包面积)

来源:互联网 发布:python snmp库 编辑:程序博客网 时间:2024/05/22 12:11

题意:一片草地上有n课树,现在你想用绳子圈出一个尽可能大的面积出来养牛。已知每只牛需要50单位的面积,问最多能养几只牛。


解题思路:凸包的面积。这里一般的思路就是先求出凸包,再以最低点为顶点分割n-2个小三角形,这样只需要求n-2个三角形的面积即可。不过这样做可能精度损失有点大。最好的方法就是用向量的叉积,当然要取绝对值。


#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int maxn = 10000;const double eps = 1e-8;struct Point{double x,y;}p[maxn],Stack[maxn];int top;double Cross(Point a,Point b,Point c){return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);  }double dis(Point a,Point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);  }int cmp(Point a,Point b)  ///设<p1,p2,...pm>为对其余点按以p0为中心的极角逆时针排序所得的点集(如果有多个点有相同的极角,除了距p0最远的点外全部移除)  {      if(Cross(a,b,p[0]) > eps)          return 1;      if(fabs(Cross(a,b,p[0])) < eps && dis(b,p[0])-dis(a,p[0]) > eps)          return 1;      return 0;  }  void Graham(int n){    top=2; ///栈顶在2,因为凸包的前两个点是不会变了      sort(p+1,p+n,cmp);      Stack[0]=p[0];   ///压p0p1p2进栈S      Stack[1]=p[1];      Stack[2]=p[2];      for(int i = 3; i < n; i++){          while(top >= 1 && Cross(p[i],Stack[top],Stack[top-1]) > eps){///有了更好的选择              top--;          }          Stack[++top]=p[i];      }  }double getArea(){double sum = fabs(Cross(Stack[1],Stack[2],Stack[0]));for(int i = 2; i < top; i++)sum += fabs(Cross(Stack[i],Stack[i+1],Stack[0]));return sum / 2.0;}int main(){int n;while(scanf("%d",&n)!=EOF){for(int i = 0; i < n; i++)scanf("%lf%lf",&p[i].x,&p[i].y);if(n < 3){printf("0\n");continue;}int k = 0;          for(int i = 0; i < n; i++) ///令p0为Q中Y-X坐标排序下最小的点              if(p[k].y > p[i].y || ((p[k].y == p[i].y) && (p[k].x > p[i].x)))                  k = i;  swap(p[0],p[k]);Graham(n);if(top < 3){printf("0\n");continue;}double ans = getArea();printf("%d\n",(int)ans/50);}return 0;}


0 0