poj 2079 Triangle (二维凸包旋转卡壳)
Description
| English | Vietnamese |
Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.
Input
The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 ≤ n ≤ 50000 and −10^4 ≤ xi, yi ≤ 10^4 for all i = 1 . . . n.
Sample Input
3
3 4
2 6
2 7
5
2 6
3 9
2 0
8 0
6 5
-1
Output
For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.
Sample output
0.50
27.00
题意:给出N个点,从中选出3个点,使其面积达到最大。
题解:我们知道这三个点肯定在凸包上,我们求出凸包之后不能枚举,因为题目n比较大,枚举的话要O(n^3)的数量级,所以采用旋转卡壳的做法:
首先确定i,j,对k进行循环,知道找到第一个k使得cross(i,j,k)>cross(i,j,k+1),如果k==i进入下一次循环。
对j,k进行旋转,每次循环之前更新最大值,然后固定一个j,同样找到一个k使得cross(i,j,k)>cross(i,j,k+1)。对j进行++操作,继续进行下一次,
直到j==k为止。
#include<cstdio>
#include<cmath>
#include<algorithm>
#define MAX 50010
using namespace std;
struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y){}
};
Point P[MAX],ch[MAX];
typedef Point Vector;
Vector operator - (Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
bool operator <(const Point &a,const Point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
int ConvexHull(Point *p,int n)
{
sort(p,p+n);
int m=;
for(int i=;i<n;i++)
{
while(m>&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--)
{
while(m>k&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
if(n>) m--;
return m;
}
double rotating_calipers(int n)
{
double ans=,tmp;
int i,j,k,kk;
n++;
for(int i=;i<n;i++)
{
j=(i+)%n;
k=(j+)%n;
while(k!=i&&j!=i)
{
while(k!=i&&Cross(ch[i]-ch[j],ch[j]-ch[k])<Cross(ch[i]-ch[j],ch[j]-ch[k+]))
k=(k+)%n;
tmp=Cross(ch[i]-ch[j],ch[j]-ch[k]);
ans=max(tmp,ans);
j=(j+)%n;
}
if(k==i)
continue;
/*kk=(k+1)%n; //kk是标记j的 j +1以后 不能是kk 也就是说j不等于k的意思 kk!=j
//环状的 可以遍历所有情况 一定不会忘了后期的长边的 无需顾虑
//不存在k到i之间有一个点k0使得ijk0很大 一一对应着都比ijk小
//为什么j==kk的时候要停止 ik这条边的意义是什么 环状可以遍历所有情况的 ik等到i变成k k变成i的时候j正好是另一半面 得证
//固定一个顶点 找出对应着这个顶点的area最大的三角形 遍历所有顶点 所以最大的那个三角形会出现三次
while(k!=i&&kk!=j)
{
tmp=Cross(ch[i]-ch[j],ch[j]-ch[k]);
ans=max(tmp,ans);
while(k!=i&&Cross(ch[i]-ch[j],ch[j]-ch[k])<Cross(ch[i]-ch[j],ch[j]-ch[k+1]))
k=(k+1)%n;
j=(j+1)%n;
}*/
}
return ans/;
}
int main()
{
int n;
while(scanf("%d",&n)&&n!=-)
{
for(int i=;i<n;i++)
scanf("%lf%lf",&P[i].x,&P[i].y);
int m=ConvexHull(P,n);
double ans=rotating_calipers(m);
printf("%.2f\n",ans);
}
return ;
}
//不能像D题poj2187一样枚举边 因为可能三个点 任意两个点不相邻
//把kk那段代码展开,会让运行时间变少100ms。时限为3000ms
//关于二维凸包旋转卡壳问题的证明还需加深理解,这道题是环状遍历,一定可以遍历所有情况的。
poj 2079 Triangle (二维凸包旋转卡壳)的更多相关文章
- poj 2187 Beauty Contest(二维凸包旋转卡壳)
D - Beauty Contest Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u ...
- HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛 - 初赛(1)
题目链接 题意:给出n个矩形,求能覆盖所有矩形的最小的矩形的面积. 题解:对所有点求凸包,然后旋转卡壳,对没一条边求该边的最左最右和最上的三个点. 利用叉积面积求高,利用点积的性质求最左右点和长度 ...
- POJ 2187 Beauty Contest(凸包+旋转卡壳)
Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, ea ...
- 【POJ 2187】Beauty Contest 凸包+旋转卡壳
xuán zhuǎn qiǎ ké模板题 是这么读吧(≖ ‿ ≖)✧ 算法挺简单:找对踵点即可,顺便更新答案. #include<cstdio> #include<cstring&g ...
- poj 2079 Triangle(旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 8917 Accepted: 2650 Descript ...
- POJ 2187 凸包+旋转卡壳
思路: 求个凸包 旋转卡壳一下 就求出来最远点对了 注意共线情况 也就是说 凸包如果有一堆点共线保留端点即可 //By SiriusRen #include <cmath> #incl ...
- [USACO2003][poj2187]Beauty Contest(凸包+旋转卡壳)
http://poj.org/problem?id=2187 题意:老题了,求平面内最远点对(让本渣默默想到了悲剧的AHOI2012……) 分析: nlogn的凸包+旋转卡壳 附:http://www ...
- UVA 10652 Board Wrapping(二维凸包)
传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...
- 【计算几何】二维凸包——Graham's Scan法
凸包 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内.右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包. 一组平面上的点, ...
随机推荐
- P1198 [JSOI2008]最大数【树状数组】
题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: L 不超过当前数列的长度. (L &g ...
- ORA-01122: 数据库文件 1 验证失败
1.SQL>shutdown abort 如果数据库是打开状态,强行关闭 2.SQL>sqlplus / as sysdba 3.SQL>startupORACLE 例程已经启动. ...
- storm实时计算实例(socket实时接入)
介绍 实现了一个简单的从实时日志文件监听,写入socket服务器,再接入Storm计算的一个流程. 源码 日志监听实时写入socket服务器 package socket; import java ...
- Apache服务配置
Apache 1.安装Apache服务 第1步:把光盘设备中的系统镜像挂载到/media/cdrom目录. [root@zhangjh ~]# mkdir -p /media/cdrom/ [root ...
- 5,pandas高级数据处理
1.删除重复元素 使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True - keep参数:指定保留哪一重复的行 ...
- 4 CSS的20/80个知识点
1.css的基本构成 样式选择器 id选择器 元素选择器 2.css的盒模型 border padding margin 3.Atom快捷键 4.程序 (1)初始程序 <!DOCTYPE htm ...
- 在ddms 里面查看data/data里面的东西 不显示data/data
今天我要查看data/anr/tarces.txt,没办法,我只有root手机. 可是root之后,我发现还是不能查看或者导出traces.txt. 后来我才知道,root之后,文件夹权限没有变,所以 ...
- easyui js拼接html,class属性失效的问题
问题:要在前一个按钮之后添加相同的样式的按钮,通过$("#cj").html(str); 这样的形式添加,却不能添加上样式 <div id="btn" c ...
- CSS系列(8) CSS后代选择器和子选择器详解
一.CSS后代选择器详解 1, 生动介绍基本概念 一个标签嵌B在另一个标签A内部,B就是A的后代. 而且,B的后代也是A的后代,这就叫“子子孙孙无穷尽也”. 比如: <div> < ...
- 手动实现一个lazyMan
这应该算一个经典的面试题了,就是一个关于流程控制的问题,要求如下 //实现一个LazyMan,可以按照以下方式调用: LazyMan("Hank")//输出: //Hi! This ...