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. Linux命令学习-top

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法. top - 01:06:48 up  1:22,   ...

  2. CLR执行模式之程序集代码的执行

    所知IL是与CPU无关的机器语言,其能访问和操作对象类型,并提供指令来创建和初始化对象,调用对象上的虚方法以及直接操作数组对象等,故可视为一种面向对象的机器语言.每种语言的存在都有其存在的价值和原因, ...

  3. ping提示小结

    1,Win7 ping 不存在的地址(请求超时) 因为路由器不理睬他. 2,R1-R2-R3 R1有默认路由,R1 ping不存在的地址(目标不可达) 3,R1-R2 R1ping本网段中不存在的地址 ...

  4. 集锦.txt

    不同的时代,有不同的需要以前,我们都以为自己可以为爱情去死,可是后来爱情死了,我们还活着. 小时候男孩子喜欢电动玩具,女孩子喜欢娃娃.长大了男孩子喜欢娃娃,女孩子喜欢电动玩具.也许这就是成长吧! 我大 ...

  5. 挂多个class还是新建class —— 多用组合,少用继承

    用css实现下面的效果图. 方案一 <style type="text/css"> .myList1 { border: 1px solid #333; padding ...

  6. 解决网站在负载均衡环境下SESSION丢失的问题

    在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下:   系统要运行在负载平衡的 Web 场环境中,而系统配置文件 ...

  7. UIPasteboard的使用

    剪贴板的使用以及自定义剪贴板. 系统剪贴板的直接调用 其实整个过程非常的简单,我就用我写的一个自定义UILable来说明调用系统剪贴板. 首先,因为苹果只放出来了 UITextView,UITextF ...

  8. 关于php析构函数的一个有趣问题

    随着面向对象编程的普遍展开,面向对象展现了其中很多有趣的问题.相信很多初学者学习php面向对象时会接触两个函数,构造函数与析构函数.构造函数似乎用的更多,析构函数用的较少(相对初学者有限编程经验而言, ...

  9. IT男的”幸福”生活"系列暂停更新通知

    首先谢谢博客园,这里给了我很多快乐.更给了大家一个学习的好地方. 在这几天更新过程中,看到了很多哥们的关注,在这里我谢谢你们,是你们给了我动力,是你们又一次给了我不一样的幸福. 在续5中我已回复了,博 ...

  10. css的小三角实现的方式

    先上一个简单的例子哈: 此时的方向向下. 如果想方向向上的话用:border-top:0;border-bottom:4px solid; 1. width:0 height:0 border宽度,颜 ...