传送门


在这里假设可以选择两个相同的点吧……

那么选出来的四个点一定会在凸包上

建立凸包,然后枚举这个四边形的对角线。策略是先枚举对角线上的一个点,然后沿着凸包枚举另一个点。在枚举另一个点的过程中可以使用旋转卡壳找到在对角线两侧、距离对角线最远的两个点,这样的四个点就可以贡献答案。总时间复杂度\(O(n^2)\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
//This code is written by Itst
using namespace std;

#define ld long double
#define eps 1e-9
#define nxt(x) ((x) % cnt + 1)
bool cmp(ld a , ld b){
    return a + eps > b && a - eps < b;
}
struct comp{
    ld x , y;
    comp(ld _x = 0 , ld _y = 0) : x(_x) , y(_y){}
    comp operator -(comp a){
        return comp(x - a.x , y - a.y);
    }
    bool operator <(const comp a)const{
        return x < a.x || cmp(x , a.x) && y < a.y;
    }
}now[2010];
int st[2010] , ind[2010];
int top , N , cnt;

inline ld dot(comp a , comp b){
    return a.x * b.y - a.y * b.x;
}

inline ld calcS(comp a , comp b , comp c){
    return fabs(dot(b - a , c - a)) / 2;
}

void init(){
    for(int i = 1 ; i <= N ; ++i){
        while(top >= 2 && dot(now[i] - now[st[top]] , now[st[top]] - now[st[top - 1]]) > -eps)
            --top;
        st[++top] = i;
    }
    for(int i = 1 ; i <= top ; ++i)
        ind[++cnt] = st[i];
    top = 0;
    for(int i = N ; i ; --i){
        while(top >= 2 && dot(now[i] - now[st[top]] , now[st[top]] - now[st[top - 1]]) > -eps)
            --top;
        st[++top] = i;
    }
    for(int i = 2 ; i < top ; ++i)
        ind[++cnt] = st[i];
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
#endif
    scanf("%d" , &N);
    for(int i = 1 ; i <= N ; ++i)
        scanf("%Lf %Lf" , &now[i].x , &now[i].y);
    sort(now + 1 , now + N + 1);
    init();
    if(cnt == 3)
        cout << fixed << setprecision(3) << calcS(now[st[1]] , now[st[2]] , now[st[3]]);
    else{
        ld ans = 0;
        for(int i = 1 ; i <= cnt ; ++i){
            int p = i , q = nxt(nxt(i));
            for(int j = nxt(nxt(i)) ; nxt(j) != i ; j = nxt(j)){
                while(calcS(now[ind[p]] , now[ind[i]] , now[ind[j]]) < calcS(now[ind[nxt(p)]] , now[ind[i]] , now[ind[j]]))
                    p = nxt(p);
                while(calcS(now[ind[q]] , now[ind[i]] , now[ind[j]]) < calcS(now[ind[nxt(q)]] , now[ind[i]] , now[ind[j]]))
                    q = nxt(q);
                ans = max(ans , calcS(now[ind[p]] , now[ind[i]] , now[ind[j]]) + calcS(now[ind[q]] , now[ind[i]] , now[ind[j]]));
            }
        }
        cout << fixed << setprecision(3) << ans;
    }
    return 0;
}

BZOJ1069 SCOI2007 最大土地面积 凸包、旋转卡壳的更多相关文章

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

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

  2. [BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳

    1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3669  Solved: 1451[Submit][Sta ...

  3. luogu P4166 [SCOI2007]最大土地面积 凸包 旋转卡壳

    LINK:最大土地面积 容易想到四边形的边在凸包上面 考虑暴力枚举凸包上的四个点计算面积. 不过可以想到可以直接枚举对角线的两个点找到再在两边各找一个点 这样复杂度为\(n^3\) 可以得到50分. ...

  4. bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳

    题目大意: 二维平面有N个点,选择其中的任意四个点使这四个点围成的多边形面积最大 题解: 很容易发现这四个点一定在凸包上 所以我们枚举一条边再旋转卡壳确定另外的两个点即可 旋(xuan2)转(zhua ...

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

    1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2277  Solved: 853[Submit][Stat ...

  6. 【BZOJ 1069】【SCOI 2007】最大土地面积 凸包+旋转卡壳

    因为凸壳上对踵点的单调性所以旋转卡壳线性绕一圈就可以啦啦啦--- 先求凸包,然后旋转卡壳记录$sum1$和$sum2$,最后统计答案就可以了 #include<cmath> #includ ...

  7. [SCOI2007]最大土地面积(旋转卡壳)

    首先,最大四边形的四个点一定在凸包上 所以先求凸包 有个结论,若是随机数据,凸包包括的点大约是\(\log_2n\)个 然鹅,此题绝对不会这么轻松,若\(O(n^4)\)枚举,只有50分 所以还是要想 ...

  8. [USACO2003][poj2187]Beauty Contest(凸包+旋转卡壳)

    http://poj.org/problem?id=2187 题意:老题了,求平面内最远点对(让本渣默默想到了悲剧的AHOI2012……) 分析: nlogn的凸包+旋转卡壳 附:http://www ...

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

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267 [思路] 凸包+旋转卡壳 求出凸包,用旋转卡壳算出凸包的直 ...

随机推荐

  1. Linux PCI设备驱动的实现思路与思想

    概述 1.PCI设备一般都具有双重身份,一方面作为PCI设备注册到Linux内核,另一方面,作为字符设备或者块设备,或者网络设备注册到Linux内核,所以,在看PCI设备时一定要注意到这点. 2. 一 ...

  2. Javascript 流程控制

    流程控制 JavaScript通过流程语句来执行程序流,程序流有若干语句组成.在正常情况下,程序中 的语句时按照书写顺序执行的,这种结构称为顺序结构.除了顺序结构之外还有选择结构和循环结构. 1.选择 ...

  3. Nginx 限制并发连接和并发请求数配置

    Nginx限制并发连接和并发请求数配置   by:授客  QQ:1033553122   测试环境 nginx-1.10.0 配置介绍 查看是否内置模块 # pwd /mnt/nginx-1.10.0 ...

  4. 排错-Loadrunner录制打不开浏览器解决方法

    排错-Loadrunner录制打不开浏览器解决方法 by:授客 QQ:1033553122 问题描述: 采用自带的web测试站点http://127.0.0.1:1080/WebTours/,进行录制 ...

  5. c++函数集锦

    1.标准C++库字符串类std::string的用法 begin       得到指向字符串开头的Iterator end       得到指向字符串结尾的Iterator rbegin        ...

  6. C#-运算符(四)

    算术运算符 +:两个操作数相加,例:2+3得5 -:第一个操作数减去第二个操作数 例:5-3得2 *:两个操作数相乘,例:2*3得6 /:分子除以分母,例:5/2得2 %:取模运算符,整除后的余数,例 ...

  7. mssql sqlserver 获取指定汉字的笔画数的方法分享

    转自:http://www.maomao365.com/?p=6421 摘要: 下文讲述计算汉字笔画数的sql函数分享,如下所示: 例:建立汉字笔画数sql函数 )) returns int as b ...

  8. C# 实体/集合差异比较,比较两个实体或集合值是否一样,将实体2的值动态赋值给实体1(名称一样的属性进行赋值)

    /// <summary> /// 实体差异比较器 /// </summary> /// <param name="source">源版本实体& ...

  9. SQLServer2016 AlwaysOn AG基于工作组的搭建笔记

    最近搭建了一套SQLServer2016 AlwaysOn AG. (后记:经实际测试,使用SQLServer2012 也同样可以在Winserver2016上搭建基于工作组的AlwaysOn AG, ...

  10. SQL 删除外键列

    一 SQL删除列的语句是: alter table tableName drop column columnName --(其中,tableName为表名,columnName为列名) 但是,如果某列 ...