POJ 2079 最大三角形面积(凸包)
Description
Input
Output
Sample Input
3
3 4
2 6
2 7
5
2 6
3 9
2 0
8 0
6 5
-1
Sample Output
0.50
27.00
Source
凸包三角:求N个点组成的三角形的最大面积?
思路:
不难想到最大三角形一定由凸包的顶点构成,难点在于怎么搜索。O(N^3)枚举会超时,旋转卡壳法O(N^2)解决问题。
点的移动:先固定一条边(红色实线),然后依次搜索第3个顶点1st,三角形面积必然是先增后减的,一旦发现开始减小了,立即终止搜索,转而移动固定边。
边的移动:固定边的移动也有讲究,固定边两点的跨度用add表示的话,add不一定是1,最大可达到(N + 1)/2,于是将此add也枚举一遍即可。
代码:
#include "cstdio"
#include "map"
#include "cmath"
#include "queue"
#include "vector"
#include "string"
#include "cstring"
#include "iostream"
#include "algorithm"
#define db double
#define ll long long
#define vec vector<ll>
#define mt vector<vec>
#define ci(x) scanf("%d",&x)
#define cd(x) scanf("%lf",&x)
#define cl(x) scanf("%lld",&x)
#define pi(x) printf("%d\n",x)
#define pd(x) printf("%f\n",x)
#define pl(x) printf("%lld\n",x)
//#define rep(i, x, y) for(int i=x;i<=y;i++)
#define rep(i,n) for(int i=0;i<n;i++)
const int N = 1e5 + ;
const int mod = 1e9 + ;
const int mOD = mod - ;
const db eps = 1e-;
const db PI = acos(-1.0);
const int inf=0x3f3f3f3f;
using namespace std;
struct P
{
db x, y;
P() {}
P(db x, db y) : x(x), y(y) {}
P operator + (P p){ return P(x + p.x, y + p.y); }
P operator - (P p){ return P(x - p.x, y - p.y); }
P operator * (db d){ return P(x*d, y*d); }
bool operator < (const P& a) const
{
if (x != a.x) return x < a.x;
else return y < a.y;
}
db dot(P p) { return x*p.x + y*p.y; }
db det(P p) { return x*p.y - y*p.x; }
}; P p[N];
// 向量AB 与 AC 的叉积 如果叉积大于0,那么C在向量AB的逆时针方向,叉积小于0则在AB的顺时针方向。如果叉积等于0,则ABC共线。
db cross(P A, P B, P C) {return (B - A).det(C - A); }
// AB和AC构成的平行四边形面积
db Area(P A, P B, P C) {return abs(cross(A, B, C)); }
// 求凸包
vector <P> ch(P *ps, int n)
{
sort(ps, ps + n);
int k = ; // 凸包的顶点数
vector <P> qs(n * ); // 构造中的凸包
for (int i = ; i < n; ++i)
{
while (k > && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) <= )
--k;
qs[k++] = ps[i];
}
for (int i = n - , t = k; i >= ; --i)
{
while (k > t && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) <= )
--k;
qs[k++] = ps[i];
}
qs.resize(k - );
return qs;
} int main()
{
int n;
while (~scanf("%d", &n) && n > )
{
for(int i = ; i < n; ++i) cd(p[i].x),cd(p[i].y);
vector <P> ps = ch(p, n);
n = ps.size();
db ans = ;
for(int ad = ; ad < (n + ) / ; ++ad)
{
int k = (ad + ) % n;
for(int i = ; i < n; ++i)
{
int j = (i + ad) % n;
db prev = Area(ps[i], ps[j], ps[k]);
for(++k; k != j && k != i; ++k)
{
if (k == n) k = ;
db cur = Area(ps[i], ps[j], ps[k]);
ans = max(ans, prev);
if (cur <= prev) break; // 达到极值
prev = cur;
}
--k; // 退出循环时,其实k已经超了一个,这里减回来
if(k == -) k += n;
}
}
printf("%.2f\n", ans / );
}
return ;
}
POJ 2079 最大三角形面积(凸包)的更多相关文章
- poj 2079(旋转卡壳求解凸包内最大三角形面积)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 9060 Accepted: 2698 Descript ...
- poj 2079 Triangle (二维凸包旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000KB 64bit IO Format: %I64d & %I64u Submit Stat ...
- (hdu step 7.1.6)最大三角形(凸包的应用——在n个点中找到3个点,它们所形成的三角形面积最大)
题目: 最大三角形 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- poj 2079 Triangle,旋转卡壳求点集的最大三角形
给出一个点集,求顶点在点集中的最大的三角形面积. 我们知道这三角形的三个点肯定在凸包上,我们求出凸包之后不能枚举,由于题目n比較大,枚举的话要O(n^3)的数量级,所以採用旋转卡壳的做法: 首先枚举三 ...
- POJ 2079 Triangle 旋转卡壳求最大三角形
求点集中面积最大的三角形...显然这个三角形在凸包上... 但是旋转卡壳一般都是一个点卡另一个点...这种要求三角形的情况就要枚举底边的两个点 卡另一个点了... 随着底边点的递增, 最大点显然是在以 ...
- ●POJ 2079 Triangle
题链: http://poj.org/problem?id=2079 题解: 计算几何,凸包,旋转卡壳 复杂度O(N^2),(O(N)什么的就不说了,我觉得我看过的O(N)方法正确性都有问题,虽然有些 ...
- poj 2079 Triangle(旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 8917 Accepted: 2650 Descript ...
- HDU 2202 最大三角形(凸包)
Problem Description 老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大.Eddy ...
- POJ 2079 Triangle [旋转卡壳]
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 9525 Accepted: 2845 Descript ...
随机推荐
- Postman工具——下载与安装(转)
https://blog.csdn.net/water_0815/article/details/53263643 今天给大家分享一款工具,好的工具能够让开发更高效,有时能成倍地提高.接下来会分几篇来 ...
- better-scroll 遇到的问题 3 (transition-group 相关)
今天在使用vue动画 transition-group 和 better-scroll 的时候,出现了下拉列表不能滚动的问题. 问题描述: 我写了一个scroll的基础组件,组件接受一个data参数, ...
- Android - 通过真实案例学习解内存泄漏问题,最终发现Android原生Bug
作为一个Android新手小白,刚到新公司,最近的工作就是在学习解各类Bug.转型之初,面临各种新知识,会有压力,但是学习的过程是快乐的. 上周刚遇上一类bug,就是应用的内存泄漏问题.最终通过前辈的 ...
- Unity3D 调用Android与IOS的剪贴板
Unity3D剪贴板 最近遇到一个需要调用Android与IOS设备本身剪贴板的需求,就是在Unity中,要将文本复制到设备本身的剪贴板中,然后在其他应用程序中都能粘贴. 最开始在网上查到的方式是使用 ...
- Struts2_使用token拦截器控制重复提交(很少用)
控制重复提交的方式:1.表单提交后页面重定向:2.Struts2.x token拦截器 大致流程: 例子: index.jsp <%@ page language="java" ...
- ansible使用6-Conditionals
when tasks: - name: "shutdown Debian flavored systems" command: /sbin/shutdown -t now when ...
- EasyUI手风琴 Tab卡使用
--案例项目代码,初始化手风琴,定义打开Tab的方法. $(result).each(function () { //m_pi_jscode,pi_jscode if (m_pi_id != this ...
- 水晶报表分组,统计,求和,sum()函数使用
--Sum()函数统计的是明细所有的和 Sum(字段名) --根据分组字段统计的和 Sum ({xh_Getdinggoudan;1.Djine} ,{xh_Getdinggoudan;1.Ddgda ...
- 【转载】#370 - Subscribe to an Event by Adding an Event Handle
You subscribe to a particular event in C# by defining an event handler-code that will be called when ...
- 读取当前路径,列出xls文件
import java.io.File; public class GetCurrentDirectory { public String GetDirectory() { File director ...
