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

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

题解:先求出凸包,O(n)枚举旋转卡壳,O(n)枚举另一个点,求最大四边形面积

/**************************************************************
    Problem: 1069
    User: walfy
    Language: C++
    Result: Accepted
    Time:892 ms
    Memory:1360 kb
****************************************************************/

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 10007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double eps=1e-6;
const int N=2000+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;

struct point{
    ll x,y;
};
point p[N],s[N];
int top,n;
ll dir(point p1,point p2,point p3)
{
    return (p3.x-p2.x)*(p2.y-p1.y)-(p3.y-p2.y)*(p2.x-p1.x);
}
ll dis(point a,point b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
ll area(point p1,point p2,point p3)
{
    return fabs(dir(p1,p2,p3));
}
bool cmp(point a,point b)
{
    ll te=dir(p[0],a,b);
    if(te<0)return 1;
    if(te==0&&dis(p[0],a)<dis(p[0],b))return 1;
    return 0;
}
void graham()
{
    int pos,minx,miny;
    minx=miny=inf;
    for(int i=0;i<n;i++)
    {
        if(p[i].x<minx||(p[i].x==minx&&p[i].y<miny))
        {
            minx=p[i].x;
            miny=p[i].y;
            pos=i;
        }
    }
    swap(p[0],p[pos]);
    sort(p+1,p+n,cmp);
    p[n]=p[0];
    s[0]=p[0],s[1]=p[1],s[2]=p[2];
    top=2;
    for(int i=3;i<=n;i++)
    {
        while(dir(s[top-1],s[top],p[i])>=0&&top>=2)top--;
        s[++top]=p[i];
    }
    ll ans=0;
    for(int i=0;i<top;i++)
    {
        int j,a1=(i+1)%top,a2=(i+3)%top;
        for(j=(i+2)%top;j!=i;j=(j+1)%top)
        {
            while(a1!=j&&area(s[(a1+1)%top],s[i],s[j])>=area(s[a1],s[i],s[j]))a1=(a1+1)%top;
            while(a2!=i&&area(s[(a2+1)%top],s[i],s[j])>=area(s[a2],s[i],s[j]))a2=(a2+1)%top;
            ans=max(ans,area(s[a1],s[i],s[j])+area(s[a2],s[i],s[j]));
        }
    }
    printf("%.3f\n",1.0*ans/2);
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y);
    graham();
    return 0;
}
/********************

********************/

原文地址:https://www.cnblogs.com/acjiumeng/p/9073981.html

时间: 2024-10-11 20:23:41

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

HDOJ 2202 最大三角形 凸包旋转卡壳求最大三角形面积

凸包旋转卡壳求最大三角形面积 最大三角形 Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3316    Accepted Submission(s): 1119 Problem Description 老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角

hdu 3934&amp;&amp;poj 2079 (凸包+旋转卡壳+求最大三角形面积)

链接:http://poj.org/problem?id=2079 Triangle Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 8173   Accepted: 2423 Description Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices

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 SCOI 2007 最大土地面积 凸包+旋转卡壳

题目大意:给出平面上的一些点,求其中四个点的最大四边形的面积. 思路:简单yy一下发现这些点肯定都在凸包上,先求个凸包.然后直接暴力肯定是不行的,我们需要一个O(n^2)的做法,比较简单的想法是枚举最后要求的四边形的一条对线,那么这个四边形就被分割成了两个三角形,剩下两个点与这条线组成的三角形的面积和就是答案. 按照旋转卡壳的思想不难发现,这两个点都是单调的.所以枚举对角线然后扫n圈就可以了. CODE: #define _CRT_SECURE_NO_DEPRECATE #include <cm

UVA 4728 Squares(凸包+旋转卡壳)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267 [思路] 凸包+旋转卡壳 求出凸包,用旋转卡壳算出凸包的直径即可. [代码] 1 #include<cstdio> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 struct Pt { 8

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle

[最小矩形面积覆盖:凸包+旋转卡壳]UVA 10173 Smallest Bounding Rectangle 题目链接:UVA 10173 Smallest Bounding Rectangle 题目大意 给你n个点,求能够覆盖所有点集的最小矩形面积. 笔者的第2道凸包题目,凸包 + 旋转卡壳,实现点集的最小矩形面积覆盖问题 ">=0"写成"<=0"坑了我一下午!QAQ 说一下思路 ①Graham's Scan法构建凸包,时间复杂度O(nlogn) ②

模板 凸包 旋转卡壳

模板  凸包  旋转卡壳 lrj <训练指南> P272 对于个点按照 x 从小到大排序,再按照 y 点从小到大排序,删除重复的点后,得到序列 p0,p1,p2..., 把 p0 和 p1 放入凸包. 从p2开始,当新点在凸包“前进”方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边 PS:判断用叉积即可 1 /******************************************** 2 计算凸包,输入点数组 p, 个数为 n , 输出点数组 ch. 函数返回凸包顶

poj 2079 Triangle,旋转卡壳求点集的最大三角形

给出一个点集,求顶点在点集中的最大的三角形面积. 我们知道这三角形的三个点肯定在凸包上,我们求出凸包之后不能枚举,因为题目n比较大,枚举的话要O(n^3)的数量级,所以采用旋转卡壳的做法: 首先枚举三角形的第一个顶点i, 初始化第二个顶点j=i+1和第三个顶点k=j+1,对k进行循环,直到找到第一个k使得cross(i,j,k)>cross(i,j,k+1),如果k==i进入下一次循环. 对j,k进行旋转,每次循环之前更新最大值,然后固定一个j,同样找到一个k使得cross(i,j,k)>cr

【BZOJ】1069: [SCOI2007]最大土地面积(凸包+旋转卡壳)

http://www.lydsy.com/JudgeOnline/problem.php?id=1069 显然这四个点在凸包上,然后枚举两个点找上下最大的三角形即可. 找三角形表示只想到三分QAQ....... 看了题解发现....这是单调的....直接扫...然后,这货叫“旋转卡壳”?是qia还是ka.... 自己一开始写的wa了........然后照标程写,,又wa了.... 后来发现是凸包写渣了QAQ...自己原来的找三角形是没问题的...我好sb..... 可是,为嘛凸包这样写会错. c