http://poj.org/problem?id=2079 (题目链接)

题意

  求凸包内最大三角形面积

Solution

  旋转卡壳。

  只会n²的做法,但是竟然过了。就是枚举每一个点,然后旋转卡壳另外两个点。先固定i,j这2个邻接的顶点。然后找出使三角形面积最大的那个k点。然后再固定i,枚举j点,由于k点是随着j点的变化在变化,所以k点不必从开头重新枚举。

  之后去网上看了下O(n)的做法,当时就感觉有点鬼,打了一遍交上去Wa了,鬼使神差拍出一组数据好像可以把网上O(n)的做法全部卡掉,但是我也还搞不清为什么这样做是错的。

数据: 

-7 0 
-5 1 
-1 5 
-2 8 

0 7 
1 5 
5 1 
8 2 
4 8 

0 -7 
4 -8 
8 -2 
5 -1 
1 -5 
-1

  这3个数据都是同一个凸包,面积都是15.00。  

O(n)代码

// poj2079
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#define esp 1e-8
#define inf 2147483640
#define LL long long
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int maxn=50010;
struct point {int x,y;}p[maxn],p0; int cross(point p0,point p1,point p2) {
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(point a,point b) {
return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(point a,point b) {
int t=cross(p0,a,b);
if (t>0) return 1;
if (t<0) return 0;
return dis(p0,a)<dis(p0,b);
}
int Graham(int n) {
if (n==1) return 1;
int k=1,top=2;
for (int i=1;i<=n;i++)
if (p[i].y==p[k].y ? p[i].x<p[k].x : p[i].y<p[k].y) k=i;
p0=p[k];p[k]=p[1];p[1]=p0;
sort(p+2,p+1+n,cmp);
for (int i=3;i<=n;i++) {
while (top>1 && cross(p[top-1],p[top],p[i])<=0) top--;
p[++top]=p[i];
}
return top;
}
double RC(int n) {
int ans=0;
p[n+1]=p[1];
int i=1,j=2,k=3,t;
while (k!=1) {
int ii=i,jj=j,kk=k;
while ((t=abs(cross(p[i],p[k],p[j])))<abs(cross(p[i],p[k+1],p[j]))) k=k%n+1;
ans=max(ans,t);
while ((t=abs(cross(p[i],p[k],p[j])))<abs(cross(p[i],p[k],p[j+1]))) j=j%n+1;
ans=max(ans,t);
while ((t=abs(cross(p[i],p[k],p[j])))<abs(cross(p[i+1],p[k],p[j]))) i=i%n+1;
ans=max(ans,t);
if (ii==i && jj==j && kk==k) k=k%n+1;
}
return (double)ans/2.0;
}
int main() {
int n;
while (scanf("%d",&n)!=EOF && n>0) {
for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
n=Graham(n);
printf("%.2f\n",RC(n));
}
return 0;
}

O(n²)代码

// poj2079
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#define esp 1e-8
#define inf 2147483640
#define LL long long
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int maxn=50010;
struct point {int x,y;}p[maxn],p0; int cross(point p0,point p1,point p2) {
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(point a,point b) {
return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(point a,point b) {
int t=cross(p0,a,b);
if (t>0) return 1;
if (t<0) return 0;
return dis(p0,a)<dis(p0,b);
}
int Graham(int n) {
if (n==1) return 1;
int k=1,top=2;
for (int i=1;i<=n;i++)
if (p[i].y==p[k].y ? p[i].x<p[k].x : p[i].y<p[k].y) k=i;
p0=p[k];p[k]=p[1];p[1]=p0;
sort(p+2,p+1+n,cmp);
for (int i=3;i<=n;i++) {
while (top>1 && cross(p[top-1],p[top],p[i])<=0) top--;
p[++top]=p[i];
}
return top;
}
double RC(int n) {
int ans=0;
p[n+1]=p[1];
for (int i=1;i<=n;i++) {
int j=i%n+1,k=(i+1)%n+1;
while (abs(cross(p[i],p[j],p[k]))<abs(cross(p[i],p[j],p[k+1]))) k=k%n+1;
while (i!=j && i!=k) {
ans=max(ans,abs(cross(p[i],p[j],p[k])));
while (abs(cross(p[i],p[j],p[k]))<abs(cross(p[i],p[j],p[k+1]))) k=k%n+1;
j=j%n+1;
}
}
return (double)ans/2.0;
}
int main() {
int n;
while (scanf("%d",&n)!=EOF && n>0) {
for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
n=Graham(n);
printf("%.2f\n",RC(n));
}
return 0;
}

  

【poj2079】 Triangle的更多相关文章

  1. 【LeetCode】Triangle 解决报告

    [称号] Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjac ...

  2. 【leetcode】Triangle (#120)

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  3. 【leetcode】triangle(easy)

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  4. 【Leetcode】Triangle

    给定一个由数字组成的三角形,从顶至底找出路径最小和. Given a triangle, find the minimum path sum from top to bottom. Each step ...

  5. 【数组】Triangle

    题目: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjace ...

  6. 【Leetcode】【Medium】Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  7. 【poj1085】 Triangle War

    http://poj.org/problem?id=1085 (题目链接) 题意 A,B两人玩游戏,在一个大三角形上放火柴,若A放上一根火柴后成功组成一个三角形,那么这个三角形就归属于A,并且A被奖励 ...

  8. 【计数】【UVA11401】 Triangle Counting

    传送门 Description 把1……n这n个数中任取3个数,求能组成一个三角形的方案个数 Input 多组数据,对于每组数据,包括: 一行一个数i,代表前i个数. 输入结束标识为i<3. O ...

  9. 【HDOJ6300】Triangle Partition(极角排序)

    题意:给定3n个点,保证没有三点共线,要求找到一组点的分组方案使得它们组成的三角形之间互不相交. n<=1e3 思路:以y为第一关键字,x为第二关键字,按x递减,y递增排序 #include&l ...

随机推荐

  1. dexDebug ExecException finished with non-zero exit value 2

    Error:Execution failed for task ':app:transformClassesWithDexForDebug'. com.android.build.api.transf ...

  2. Volley(五)—— 自定义Request

    详细解读Volley(四)—— 自定义Request Volley中提供了几个Request,如果我们有特殊的需求,完全可以自定义Request的,自定义Request自然要继承Request,那么本 ...

  3. $apply方法的作用

    $apply方法是用来触发脏检查,它在控制器里监听一个变量,每当这个变量的值改变的时候,它会去与最初的值做一次比较,然后HTML页面就会及时更新该变量的值(将最新的值赋值到html页面的view层或M ...

  4. JavaScript---闭包和作用域链

    作用域和作用域链: 参考文章 :http://www.cnblogs.com/malinlin/p/6028842.html  http://www.cnblogs.com/lhb25/archive ...

  5. Maven 小结

    Maven 的各项功能通过插件实现,有需要的时候学习那些插件的配置即可 一般一个大型项目会有 A:父管理工程,定义了所有的依赖和插件 B:工具工程 C:web 项目的父工程,同时也是一个聚合工程 D: ...

  6. android.hardware.Camera类及其标准接口介绍

    android.hardware.Camera类及其标准接口介绍,API level 19 http://developer.android.com/reference/android/hardwar ...

  7. [转]在 Eclipse 中嵌入 NASA World Wind Java SDK

    使用此开源 SDK 开发 GIS 应用程序 NASA 开发的开源 World Wind Java (WWJ) SDK 为地理信息系统(Geographic Information Systems,GI ...

  8. StringBuffer类 和 StringBuilder类

    上一篇中讲解了String类的用法.那么String有什么特点呢? 字符串特点:字符串是常量,其值在创建后就不能被修改.字符串的内容一旦发生变化,就会创建一个新的对象. 代码验证字符串特点: publ ...

  9. 通过HttpClient来调用Web Api接口~续~实体参数的传递

    并且我们知道了Post,Put方法只能有一个FromBody参数,再有多个参数时,上讲提到,需要将它封装成一个对象进行传递,而这讲主要围绕这个话题来说,接口层添加一个新类User_Info,用来进行数 ...

  10. MVC5 + EF6 + Bootstrap3 (14) 分部视图PartialView

    Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-partialview.html 系列教程:MVC5 + E ...