【bzoj1069】最大土地面积

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

Solution

显然的,我们枚举对角线,我们现在的问题是找离对角线最远的点是哪两个点

于是我们发现,当A固定,C变为逆时针的下一个点的时候,

B,D也一定是单调逆时针变动的

这里运用旋转卡壳的思想

所以这题本质是旋转卡壳,只是更加简单了

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#include<vector>
#include<set>
#define il inline
#define re register
using namespace std;
typedef double db;
const int N=3001;
const db eps=1e-8;
struct P{db x,y;} a[N],s[N];
int n,top;db ans=0;
il P operator-(P a,P b){
    return (P){a.x-b.x,a.y-b.y};
}
il db operator*(P a,P b){
    return a.x*b.y-a.y*b.x;
}
il db S(P a,P b,P c){
    return fabs((a-b)*(a-c))/2;
}
il db dis(P a){
    return a.x*a.x+a.y*a.y;
}
il db cmp(P x,P y){
    return (x-a[1])*(y-a[1])>0;
}
il void print(P a){
    printf("(%lf,%lf)\n",a.x,a.y);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    for(int i=1;i<=n;i++)
        if(a[i].y<a[1].y||(a[i].y==a[1].y&&a[i].x<a[1].x)) swap(a[1],a[i]);
    sort(a+2,a+n+1,cmp);
    s[1]=a[1];s[2]=a[2];top=2;
    for(int i=3;i<=n;i++){
        while(top>1&&(a[i]-s[top-1])*(s[top]-s[top-1])>=0) top--;
        s[++top]=a[i];
    }
    if(top==4){
        ans=S(s[1],s[2],s[3])+S(s[1],s[3],s[4]);
        printf("%.3lf",ans);
        return 0;
    }
//    for(int i=1;i<=top;i++) print(s[i]);
    for(int i=0;i<top;i++) s[i]=s[i+1];
    n=top;
    for(int i=0;i<n;i++){
        for(int j=(i+1)%n,k=(i+2)%n,l=(i+3)%n;k!=(i-2+n)%n;k=(k+1)%n){
            while(S(s[i],s[j],s[k])<S(s[i],s[(j+1)%n],s[k])) j=(j+1)%n;
            while(S(s[i],s[l],s[k])<S(s[i],s[(l+1)%n],s[k])) l=(l+1)%n;
        //    cout<<i<<" "<<j<<" "<<k<<" "<<l<<endl;
            ans=max(S(s[i],s[j],s[k])+S(s[i],s[k],s[l]),ans);
        }
    }
    printf("%.3lf",ans);
    return 0;
}
时间: 2024-10-29 10:46:08

【bzoj1069】最大土地面积的相关文章

BZOJ1069: [SCOI2007]最大土地面积

传送门 对于给定的点,先求出凸包,听说水平序求凸包会被卡..亲测不会 然后对于求出来的凸包,求出每一个对踵点.然后对于每一个对踵点,遍历凸包上每一个点,求出最大的叉积和最小的叉积,绝对值的累加即位最大面积. //BZOJ1069 //by Cydiater //2017.1.29 #include <iostream> #include <queue> #include <map> #include <cstring> #include <string

【BZOJ1069】【SCOI2007】最大土地面积 凸包 单调性

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46591735"); } 题解: 先求凸包,然后: 枚举点 i ,然后对于 点 j 得到的 i 与 j (有序) 中间的点,以及 j 与 i (有序) 中间的点,都是单调的. 代码: #include <cmat

bzoj1069: [SCOI2007]最大土地面积 凸包+旋转卡壳求最大四边形面积

在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. 题解:先求出凸包,O(n)枚举旋转卡壳,O(n)枚举另一个点,求最大四边形面积 /************************************************************** Problem: 1069 User: walfy Language: C++ Result: Accepted Time:892 ms Memory:1360 kb ****

1069: [SCOI2007]最大土地面积

1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 2961  Solved: 1162[Submit][Status][Discuss] Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标. Output 最大的多边形面积,答案精确到

bzoj 1069 [SCOI2007]最大土地面积(旋转卡壳)

1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2277  Solved: 853[Submit][Status][Discuss] Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标. Output 最大的多边形面积,答案精确到小

【BZOJ 1069】 [SCOI2007]最大土地面积

1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 1677  Solved: 588 [Submit][Status] Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标. Output 最大的多边形面积,答案精确到小数点后3位.

[POJ2187][BZOJ1069]旋转卡壳

旋转卡壳 到现在依然不确定要怎么读... 以最远点对问题为例,枚举凸包上的两个点是最简单的想法,时间复杂度O(n2) 我们想象用两条平行线卡着这个凸包,当其中一个向某个方向旋转的时候另一个显然也是朝同样的方向旋转 所以在枚举其中一条边的过程中完全没有必要重新枚举另一条边 而且对于一条边而言,凸包上的点到这条边的距离是满足单峰性质的 所以线性的做法就出来啦 ↓代码非常短很优秀~ procedure Roatating_Calipers; begin stack[len+1]:=stack[1];j

【BZOJ】【1069】【SCOI2007】最大土地面积

计算几何/旋转卡壳 从已知点中选出四个使得选出的四边形面积最大,很明显我们应该在凸包上搞. 我一开始的思路是:枚举 i ,找到 i 的对锺点cur1,这两个点将凸包分成了两半,我们在左半中枚举一个 j ,然后在右半中找一个离 j 最远的“对锺点”(可能不是?反正找的是最远……)cur2,然后求cur1和cur2都是单调的,复杂度为枚举 i, j的$O(n^2)$ 然而跪了= =然后我去Orz了proverbs的题解,得到启示:我们可以枚举一条对角线,然后在左半和右半中各找一条跟这条对角线最远的点

凸包(BZOJ1069)

顶点一定在凸包上,我们枚举对角线,观察到固定一个点后,随着另一个点的增加,剩下两个点的最优位置一定是单调的,于是就得到了一个优秀的O(n^2)做法. #include <cstdio> #include <algorithm> const int N = 2005; int n,r,p1,p2,q[N]; double ans; struct nd { double x,y; bool operator < (const nd &b) const {return x