poj-2079 Triangle

来源:互联网 发布:淘宝商品存在交易风险 编辑:程序博客网 时间:2024/05/18 02:59

题意:

给出平面上的n个点,求其中三个点组成的最大三角形面积;

n<=50000;


题解:

一道xuanzhuankake题;

O(n^3)的做法很显然,最优解一定在凸包上也很显然;

所以考虑到凸包上去找答案;

首先枚举一个顶点,将第二个顶点和它的连线视为底;

这个长度越大越好,即它们为对踵点对;

这时也枚举第三个点来更新答案;

模拟一下过程可以发现,后两个点的取值都是单调的;

所以随着第一个点绕了一圈,第二,三个也不会绕太多圈;

这个复杂度是O(n)的,算上之前求凸包的时间,总复杂度O(nlogn);

然而poj只是在骗你,其实这题凸包上O(n^2)枚举可A;


代码:


#include<stdio.h>#include<string.h>#include<algorithm>#define N 55000using namespace std;struct Point{int x,y;Point(){}Point(int _,int __):x(_),y(__){}void read(){scanf("%d%d",&x,&y);}friend bool operator <(Point a,Point b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}friend Point operator -(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}friend int operator ^(Point a,Point b){return a.x*b.y-a.y*b.x;}}a[N],st[2][N];int top[2];int calc(int i,int j,int k){i=(i-1)%top[0]+1;j=(j-1)%top[0]+1;k=(k-1)%top[0]+1;return abs(st[0][i]-st[0][j]^st[0][i]-st[0][k]);}double RC(){int i,j,k,ans;for(i=1,j=2,k=3,ans=0;i<=top[0];i++){ans=max(calc(i,j,k),ans);while(calc(i,j,k)<calc(i,j,k+1))ans=max(calc(i,j,++k),ans);while(calc(i,j,k)<calc(i,j+1,k))ans=max(calc(i,++j,k),ans);}return ans/2.0;}int main(){int n,m,i,j,k;while(scanf("%d",&n)&&n!=-1){for(i=1;i<=n;i++)a[i].read();sort(a+1,a+n+1);st[0][top[0]=1]=a[1];for(i=2;i<=n;i++){while(top[0]>1&&(st[0][top[0]].y-st[0][top[0]-1].y)*(a[i].x-st[0][top[0]].x)<(a[i].y-st[0][top[0]].y)*(st[0][top[0]].x-st[0][top[0]-1].x))top[0]--;st[0][++top[0]]=a[i];}st[1][top[1]=1]=a[1];for(i=2;i<=n;i++){while(top[1]>1&&(st[1][top[1]].y-st[1][top[1]-1].y)*(a[i].x-st[1][top[1]].x)>(a[i].y-st[1][top[1]].y)*(st[1][top[1]].x-st[1][top[1]-1].x))top[1]--;st[1][++top[1]]=a[i];}for(i=top[1]-1;i>1;i--)st[0][++top[0]]=st[1][i];printf("%.2lf\n",RC());}return 0;}



0 0
原创粉丝点击