bzoj1069-最大土地面积
题目
给定\(n\ (n\le 2000)\)个坐标,求四个坐标使得围起来的四边形面积最大。
分析
最暴力的想法是枚举四个点,然而肯定超时。接着不知道怎么想到中途相遇,然而一点关系都没有。这里用到了一个单调性:
如果在凸包上确定了一个点\(x\),令\(x\)逆时针方向的第一个点为\(y\),这时确定了一个点\(z\)使得\(S_{\triangle XYZ}最大,那么当\)y\(逆时针移动的时候,使得三角形面积最大的点\)z\(就会不动或逆时针移动。这个性质发展成为我们说的旋转卡壳。
这就是说,如果在凸包上确定了一个点,那么我们可以\)O(n)\(求出包含这个点的所有凸包上的四边形的最大面积。
所以我们可以枚举所有点,在\)O(n^2)$中求出答案。
代码
这里有几个地方需要注意到。
- 求凸包极角排序的时候,选择的基础点一定是最下面,最左边的,而不可以仅仅是最下面的,否则会出现\(0\)和\(-0\)这种情况。
- 在求凸包单调栈弹出的时候,要用小于等于号,否则如果有重点的情况就会出现问题。
- 在计算答案时,每次移动\(j\)的时候要记得更新\(s1\)和\(s2\)。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=2e3+10;
struct node {
double x,y;
} a[maxn],sta[maxn];
int top=0;
double P(double x) {
return x*x;
}
double dis(node a,node b) {
return sqrt(P(a.x-b.x)+P(a.y-b.y));
}
double cross(node a,node b,node c) {
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool cmp(node e,node f) {
double tmp=cross(a[1],e,f);
if (tmp>0) return true;
if (tmp<0) return false;
return dis(a[1],e)<dis(a[1],f);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("my.out","w",stdout);
#endif
int n;
scanf("%d",&n);
for (int i=1;i<=n;++i) {
scanf("%lf%lf",&a[i].x,&a[i].y);
if (a[i].y<a[1].y || (a[i].y==a[1].y && a[i].x<a[1].x)) swap(a[1],a[i]); // here
}
sort(a+2,a+n+1,cmp);
sta[top=1]=a[1];
for (int i=2;i<=n;++i) {
while (top>1 && cross(sta[top-1],sta[top],a[i])<=0) --top; // here
sta[++top]=a[i];
}
if (top<=4) {
double ans=0;
if (top>2) ans=cross(sta[1],sta[2],sta[3]);
if (top==4) ans+=cross(sta[1],sta[3],sta[4]);
ans/=2;
printf("%.3lf\n",ans);
return 0;
}
double ans=0;
for (int i=1;i<=top-2;++i) {
int j=(i+1)%top+1,k=i%top+1,l,id=j%top+1;
double s1=cross(sta[i],sta[k],sta[j])/2;
double s2=0;
for (l=id;l!=i;l=l%top+1) {
double tmp=cross(sta[i],sta[j],sta[l])/2;
if (tmp>s2) s2=tmp,id=l;
}
l=id;
ans=max(ans,s1+s2);
for (j=j%top+1;j%top+1!=i;j=j%top+1) {
s1=cross(sta[i],sta[k],sta[j])/2; // here
s2=cross(sta[i],sta[j],sta[l])/2; // here
if (l==j) l=l%top+1,s2=cross(sta[i],sta[j],sta[l])/2;
while (k%top+1!=j && cross(sta[i],sta[k%top+1],sta[j])/2>s1) k=k%top+1,s1=cross(sta[i],sta[k],sta[j])/2;
while (l%top+1!=i && cross(sta[i],sta[j],sta[l%top+1])/2>s2) l=l%top+1,s2=cross(sta[i],sta[j],sta[l])/2;
ans=max(ans,s1+s2);
}
}
printf("%.3lf\n",ans);
}
bzoj1069-最大土地面积的更多相关文章
- 【BZOJ-1069】最大土地面积 计算几何 + 凸包 + 旋转卡壳
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 2707 Solved: 1053[Submit][Sta ...
- bzoj1069 SCOI2007 最大土地面积
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 2560 Solved: 983 Description ...
- bzoj1069 [SCOI2007]最大土地面积 旋转卡壳
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3767 Solved: 1501[Submit][Sta ...
- BZOJ1069 SCOI2007最大土地面积(凸包+旋转卡壳)
求出凸包,显然四个点在凸包上.考虑枚举某点,再移动另一点作为对角线,容易发现剩下两点的最优位置是单调的.过程类似旋转卡壳. #include<iostream> #include<c ...
- BZOJ1069 [SCOI2007]最大土地面积 【凸包 + 旋转卡壳】
题目链接 BZOJ1069 题解 首先四个点一定在凸包上 我们枚举对角线,剩下两个点分别是两侧最远的点 可以三分,复杂度\(O(n^2logn)\) 可以借鉴旋转卡壳的思想,那两个点随着对角线的一定单 ...
- [BZOJ1069][SCOI2007]最大土地面积(水平扫描法求凸包+旋转卡壳)
题意:在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成. 的多边形面积最大.n<=2000. 先求凸包,再枚举对角线,随着对角线的斜率上升,另外两 ...
- [BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3669 Solved: 1451[Submit][Sta ...
- [Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3629 Solved: 1432[Submit][Sta ...
- BZOJ1069 SCOI2007 最大土地面积 凸包、旋转卡壳
传送门 在这里假设可以选择两个相同的点吧-- 那么选出来的四个点一定会在凸包上 建立凸包,然后枚举这个四边形的对角线.策略是先枚举对角线上的一个点,然后沿着凸包枚举另一个点.在枚举另一个点的过程中可以 ...
- 【bzoj1069】最大土地面积
Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接下来N行,每行2个数x,y ...
随机推荐
- Java设计模式(22)——行为模式之状态模式(State)
一.概述 概念 再引用网友的说通俗一点: State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判 ...
- 【转】Odoo:基本字段类型
class Stage(models.Model): _name = 'todo.task.stage' _order = 'sequence,name' # String fields: name ...
- Error starting mongod. /var/run/mongodb/mongod.pid exists.启动mongodb报错
linux上安装mongodb,启动时报上面的错,解决如下: 解决方法: 1.删除mongod.pid文件 rm -rf /var/run/mongodb/mongod.pid 2.修改/tmp/mo ...
- CDN 缓存策略(转)
1.CDN加速原理 通过动态域名解析,网友的请求被分配到离自己最快的服务器.CDN服务器直接返回缓存文件或通过专线代理原站的内容. 网络加速+内容缓存,有效提供访问速度 2.CDN节点数量 ...
- 「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
题意(CodeForces 588E) 给定一棵\(n\)个点的树,给定\(m\)个人(\(m\le n\))在哪个点上的信息,每个点可以有任意个人:然后给\(q\)个询问,每次问\(u\)到\(v\ ...
- grep命令及正则
文本查找 grep,egrep,fgrep grep :Global Research 根据模式搜索文本,并将符合模式的文本行显示出来 模式:Pattern,文本字符和正则的元字符组合而成匹配条件 g ...
- VMware 15.0下载及安装教程
虚拟机 VMware WorkStation Pro15 下载及安装详细解 9虚拟机 VMware WorkStation Pro15 下载及安装详细解. 虚拟机官方网站: https://www.v ...
- 90 [LeetCode] Subsets2
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the ...
- 吴恩达j机器学习之过拟合
五.编程作业: 见:https://www.cnblogs.com/tommyngx/p/9933803.html
- LeetCode 120——三角形最小路径和
1. 题目 2. 解答 详细解答方案可参考北京大学 MOOC 程序设计与算法(二)算法基础之动态规划部分. 从三角形倒数第二行开始,某一位置只能从左下方或者右下方移动而来,因此,我们只需要求出这两者的 ...