zoukankan      html  css  js  c++  java
  • [BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳

    1069: [SCOI2007]最大土地面积

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 3669  Solved: 1451
    [Submit][Status][Discuss]

    Description

      在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
    的多边形面积最大。

    Input

      第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。

    Output

      最大的多边形面积,答案精确到小数点后3位。

    Sample Input

    5
    0 0
    1 0
    1 1
    0 1
    0.5 0.5

    Sample Output

    1.000

    HINT

    数据范围 n<=2000, |x|,|y|<=100000

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define eps 1e-9
     8 using namespace std;
     9 struct point {
    10     double x,y;
    11     bool operator <(const point t) const {
    12         return fabs(t.x-x)>eps?x<t.x:y<t.y;
    13     }
    14 }p[2500],s[2500];
    15 point operator -(point t1,point t2) {
    16     return (point){t1.x-t2.x,t1.y-t2.y};
    17 }
    18 double operator *(point t1,point t2) {
    19     return t1.x*t2.y-t2.x*t1.y;
    20 }
    21 int n,top;
    22 void get() {
    23     s[0]=p[1];
    24     for(int i=2;i<=n;i++) {
    25         while(top&&(s[top]-s[top-1])*(p[i]-s[top])>=0) top--;
    26         s[++top]=p[i];
    27     }
    28     int tmp=top;
    29     for(int i=n-1;i>=1;i--)  {
    30         while(top>tmp&&(s[top]-s[top-1])*(p[i]-s[top])>=0) top--;
    31         s[++top]=p[i];
    32     }
    33 }
    34 double cnts(point a,point b,point c) {
    35     return fabs((b-a)*(c-a))/2;
    36 }
    37 int main() {
    38     double maxn=0;
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    41     sort(p+1,p+n+1);
    42     get();
    43     for(int i=0;i<top;i++) {
    44         int j=(i+2)%top,k=(i+1)%top,w=(j+1)%top;
    45         while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+1])) k=(k+1)%top;
    46         double ans1=cnts(s[i],s[j],s[k]);
    47         while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+1])) w=(w+1)%top;
    48         double ans2=cnts(s[i],s[j],s[w]);
    49         double ans=0;
    50         while(ans1+ans2>ans) {
    51             ans=ans1+ans2;
    52             j=(j+1)%top;
    53             while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+1])) k=(k+1)%top;
    54             ans1=cnts(s[i],s[j],s[k]);
    55             while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+1])) w=(w+1)%top;
    56             ans2=cnts(s[i],s[j],s[w]);
    57         }
    58         maxn=max(maxn,ans);
    59     }
    60     printf("%.3lf",maxn);
    61 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    2019年2月8日训练日记(文件操作知识点小结)
    2019年2月7日训练日记
    2019年2月6日训练日记
    2019年2月5日训练日记
    2019年2月4日训练日记(递归学习小结)
    【Java】Java中的IO流
    【Java】Java中线程的使用
    【Java】Java图形化用户界面-GUI
    【Java】Java中的集合类
    C++程序学习之实现手机通讯录功能模拟
  • 原文地址:https://www.cnblogs.com/wls001/p/7762478.html
Copyright © 2011-2022 走看看