题目链接

BZOJ1069

题解

首先四个点一定在凸包上

我们枚举对角线,剩下两个点分别是两侧最远的点

可以三分,复杂度\(O(n^2logn)\)

可以借鉴旋转卡壳的思想,那两个点随着对角线的一定单调不减,可以用两个指针维护,复杂度\(O(n^2)\)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 2005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
struct point{double x,y;}p[maxn],t[maxn];
inline bool operator <(const point& a,const point& b){
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline point operator +(const point& a,const point& b){
return (point){a.x + b.x,a.y + b.y};
}
inline point operator -(const point& a,const point& b){
return (point){a.x - b.x,a.y - b.y};
}
inline double operator *(const point& a,const point& b){
return a.x * b.x + a.y * b.y;
}
inline double cross(const point& a,const point& b){
return a.x * b.y - a.y * b.x;
}
inline double dis(const point& a,const point& b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
inline double S(const point& a,const point& b,const point& c){
return fabs(0.5 * cross(c - a,c - b));
}
int n,st[maxn],top;
void cal(){
sort(p + 1,p + 1 + n);
st[top = 1] = 1;
for (int i = 2; i <= n; i++){
while (top > 1 && cross(p[i] - p[st[top]],p[st[top]] - p[st[top - 1]]) <= 0)
top--;
st[++top] = i;
}
int tmp = top;
for (int i = n - 1; i; i--){
while (top > tmp && cross(p[i] - p[st[top]],p[st[top]] - p[st[top - 1]]) <= 0)
top--;
st[++top] = i;
}
n = --top;
for (int i = 1; i <= n; i++) t[i] = p[st[i]];
for (int i = 1; i <= n; i++) p[i] = t[i];
}
void solve(){
if (n == 3){printf("%.3lf",S(p[1],p[2],p[3])); return;}
double ans = 0;
for (int i = 1; i <= n - 3; i++){
int x = i + 1,y = i + 3;
for (int j = i + 3; j <= n; j++){
if (S(p[i],p[i + 2],p[j]) > S(p[i],p[i + 2],p[y]))
y = j;
}
ans = max(ans,S(p[i],p[i + 2],p[x]) + S(p[i],p[i + 2],p[y]));
for (int j = i + 3; j <= n; j++){
while (x + 1 < j && S(p[i],p[j],p[x + 1]) > S(p[i],p[j],p[x])) x++;
while (y + 1 <= n && S(p[i],p[j],p[y + 1]) > S(p[i],p[j],p[y])) y++;
ans = max(ans,S(p[i],p[j],p[x]) + S(p[i],p[j],p[y]));
}
}
printf("%.3lf\n",ans);
}
int main(){
n = read();
if (n <= 2) {puts("0"); return 0;}
REP(i,n) scanf("%lf%lf",&p[i].x,&p[i].y);
cal();
//REP(i,n) printf("(%lf,%lf)\n",p[i].x,p[i].y);
solve();
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. BZOJ1069 SCOI2007 最大土地面积 凸包、旋转卡壳

    传送门 在这里假设可以选择两个相同的点吧-- 那么选出来的四个点一定会在凸包上 建立凸包,然后枚举这个四边形的对角线.策略是先枚举对角线上的一个点,然后沿着凸包枚举另一个点.在枚举另一个点的过程中可以 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Spring学习(一)-----Spring 模块详解

    官方下载链接:http://repo.spring.io/release/org/springframework/spring/ Spring 模块详解: Core 模块 spring-beans-3 ...

  2. 在腾讯云上安装mysql遇到的问题

    卸载mysql: 1.sudo apt-get autoremove --purge mysql-server-5.5 5.5 是数据库版本, mysql -v 显示版本信息 2.sudo apt-g ...

  3. json_encode替代函数

    <?php   function jsonEncode($var) {     if (function_exists('json_encode')) {         return json ...

  4. VMWARE网络配置内网与外网互ping

    新增网络适配器 设置自定义VMnet0 自动桥接 NAT的网络要配置网关 我们在CentOS中打开ifcfg-ens33文件(每个系统文件名都不同,但都是以ifcfg-ens33开头的文件),进行修改 ...

  5. Literature Books

    Lean In (Sheryl Sandberg) Option B (Sheryl Sandberg) Ready Player One

  6. kafka浅谈

    关键词 producer       生产者 broker          缓存代理 consumer     消费者 partition       分区 topic            主题 ...

  7. JS 数组方法 array数组声明 元素的添加和删除 等

    声明数组 var arr1 = [1,2,3,4,5]; var arr2 = new Array(100); //声明长度为100的arr2数组. arr2=[]; arr2.length = 10 ...

  8. KNY团队与“易校”小程序介绍

    一.团队介绍 “KNY”团队是软件工程专业中的一支充满了斗志,充满了自信的队伍,由三人组成,每个队员都在为我们共同一致的目标而努力:我们三个人的小程序的知识都相对薄弱,但我们不甘落后,一直在努力的学习 ...

  9. 博弈--ZOJ 3084 S-Nim(SG)

    题意: 首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个数 之后输入 一个m 表示接下来对于这个集合要进行m次询问  之后m行 每行输入一个n 表示有n个堆  ...

  10. lintcode-436-最大正方形

    436-最大正方形 在一个二维01矩阵中找到全为1的最大正方形 样例 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 返回 4 标签 动态规划 爱彼迎 脸书 思路 使用 ...