Summer holiday (求解凸包)

Summer holiday was coming! Xiaomao went back to his hometown where he yearn day and night, his hometown has picturesque scenery. There is a big forest beside his village. There are n trees in the forest.
Now they want to across the forest with a rope (the rope won't cross). Try to find 3 trees in this tree on the rope which can make the area of the surrounded largest. Work out the area of it.

Input

The input will consist of several test cases. The first line contains a positive integer N(3<=N<=10^6), the number of trees, followed N lines, each gives the (xi, yi ) coordinates.

Output

Print the largest area, one number a line with two decimal places.

Sample Input

4
0 0
1 1
0 1
1 0

Sample Output

0.50

题意:给出n个点,求出里面最大三角形的面积

思路:最大三角形,一定是由最大凸包里的某三点构成

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e6+5;
struct Point{
	int x,y;
	Point(){
	}
	Point(int xx,int yy){
		x=xx;
		y=yy;
	}
}p[N];
int sta[N],top;
int n;
Point operator -(const Point a,const Point b){
	return Point(a.x-b.x,a.y-b.y);
}
int operator*(const Point a,const Point b){
	return a.x*b.y-a.y*b.x;
}
int cross(Point a,Point b,Point c){
    return (b-a)*(c-a);
}
int dis(Point a,Point b){
	int X=(a.x-b.x)*(a.x*b.x);
	int Y=(a.y-b.y)*(a.y-b.y);
	return X+Y;
}
bool cmp(Point b,Point c){
	Point a=p[0];
	int ans=cross(a,b,c);
	if(ans==0) return dis(a,b)>dis(a,c);
	return ans>0;
}
bool judge(Point a,Point b){
	if(a.y==b.y) return a.x<b.x;
	return a.y<b.y;
}
void solve(){
	sta[0]=0;
	sta[1]=1;
	top=1;
	for(int i=2;i<n;i++){
		while(top&&cross(p[sta[top-1]],p[sta[top]],p[i])<0) top--;
		sta[++top]=i;
	}
	sta[++top]=0;
	sta[++top]=1;
	top++;
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d%d",&p[i].x,&p[i].y);
		}
		int t=0;
		for(int i=1;i<n;i++)
		   if(judge(p[i],p[t])) t=i;
		swap(p[t],p[0]);
		sort(p+1,p+n,cmp);
        solve();
        int ans=0;
        for(int i=0;i<top;i++)
        for(int j=i+1;j<top;j++)
        for(int k=j+1;k<top;k++)
          ans=max(ans,cross(p[sta[i]],p[sta[j]],p[sta[k]]));
        printf("%.2f\n",0.5*ans);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值