计算几何 BAPC 14 C itadel Construction (Gym 100526C )

来源:互联网 发布:淘宝日系男装店铺排行 编辑:程序博客网 时间:2024/05/21 10:27


题目意思是给定n各点,找四个点,使这四个点围成的面积最大。

首先用granham计算最大凸包,然后枚举最大的四边形,但是枚举的时候要注意优化。

可以这么考虑,若使四边形abcd面积最大,一定是ac最长的时候,再找最优的b跟d,凑成abcd。

    #define SIZE 1001      struct point_t{          llt x,y;      }P[SIZE];            //叉积,OA×OB      inline llt cross(point_t const&O,point_t const&A,point_t const&B){          llt xoa = A.x - O.x;          llt yoa = A.y - O.y;          llt xob = B.x - O.x;          llt yob = B.y - O.y;          return xoa * yob - xob * yoa;      }            //A如果比B更靠下更靠左返回真      inline bool isLowLeft(point_t const&A,point_t const&B){          return A.y < B.y || ( A.y == B.y && A.x < B.x );      }            //按照对于pO的极角排序,极角相等的距离远的排在前面,因为后面要做一个unique      point_t* pO;      bool comp4Graham(point_t const&A,point_t const&B){          llt t = cross(*pO,A,B);          if ( t ) return t > 0LL;                llt a1 = A.x > pO->x ? A.x - pO->x : pO->x - A.x;          llt a2 = B.x > pO->x ? B.x - pO->x : pO->x - B.x;          if ( a1 != a2 ) return a1 > a2;                a1 = A.y > pO->y ? A.y - pO->y : pO->y - A.y;          a2 = B.y > pO->y ? B.y - pO->y : pO->y - B.y;          return a1 > a2;      }            //相对于pO是否极角相等      inline bool isEqPolar(point_t const&A,point_t const&B){          return 0LL == cross(*pO,A,B);      }            //Graham求凸包,结果当中没有共线点,起点总是最下最左点      int Graham(point_t P[],int n){          if ( 1 == n ) return 1;                //寻找最下最左点          point_t *p = min_element(P,P+n,isLowLeft);                //交换          swap(*p,P[0]);                if ( 2 == n ) return 2;                //按极角排序,极角相等,距离近的排在前面          pO = P;          sort(P+1,P+n,comp4Graham);                //将相对于pO的共线点均剔除,只保留最后一个          p = unique(P+1,P+n,isEqPolar);          n = p - P;                //真正的Graham循环          int top = 2;          for(int i=2;i<n;++i){              while( top > 1 && cross(P[top-2],P[top-1],P[i]) <= 0LL )                  --top;              P[top++] = P[i];          }          return top;      }            int area2( point_t const&p1,point_t const&p2,point_t const&p3){          return abs( p2.x*p3.y - p2.x*p1.y - p1.x*p3.y + p1.x*p1.y - p2.y*p3.x  + p2.y*p1.x + p1.y*p3.x - p1.y*p1.x );      }            int main(){          int t;scanf("%d",&t);          while(t--){              int n;scanf("%d",&n);              for(int i=0;i<n;++i)scanf("%d%d",&P[i].x,&P[i].y);              n = Graham(P,n);                            int a,b,c,d;              int ans = -1;              for( a = 0;a < n; ++a){                  b = a;                  d = a+1;                  for ( c = a+1; c < n;++c ) {                      while( b < c && area2(P[a],P[b+1],P[c]) >= area2(P[a],P[b],P[c]) )                          b++;                      //while( d < c) d++;                      while( d < n-1 && area2(P[a],P[c],P[d+1]) >= area2(P[a],P[c],P[d]) )                          d++;                      ans = max(ans, area2(P[a],P[b],P[c]) + area2(P[a],P[c],P[d]) );                  }              }              if ( ans % 2 ){                  printf("%d.5\n",ans/2);              }else printf("%d\n",ans/2);                      }          return 0;      }  


0 0