最大空凸包模板 && HDU 6219: Empty Convex Polygons

 

Empty Convex Polygons

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 543    Accepted Submission(s): 142

Problem Description

Given a set of distinct points S on a plane, we define a convex hole to be a convex polygon having any of thegiven points as vertices and not containing any of the given points in its interior. In addition to the vertices, other given points may lie on the perimeter of the polygon. We want to find a convex hole as above forming the convexpolygon with the largest area.

Input

This problem has several test cases.
The first line of input contains an integer t (1 ≤ t ≤ 100) indicating the total number of cases. For each test case,the first line contains the integer n (3 ≤ n ≤ 50). Each of the following n lines describes a point with two integers x and y where -1000 ≤ x, y ≤ 1000.
We guarantee that there exists at least one non-degenerated convex polygon.

Output

For each test case, output the largest area of empty convex polygon, with the precision of 1 digit.
Remark: The corollary of Pick’s theorem about the polygon with integer coordinates in that says the area of it iseither ends to .0 or .5.

Sample Input

4 3 0 0 1 0 0 1 5 0 0 1 0 2 0 0 1 1 1 5 0 0 3 0 4 1 3 5 -1 3 6 3 1 1 0 2 0 3 0 4 0 5 0

Sample Output

0.5 1.5 17.0 2.0

 

T组测试数据,每组n个点

求出n个点以其中若干个点为顶点的最大凸多边形面积,要求多边形内部不能有其它点

复杂度O(n^3)

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
typedef struct Point
{
	int x, y;
	Point() {}
	Point(int x, int y): x(x),y(y) {}
	Point operator + (const Point &b) const {  return Point(x+b.x,y+b.y);  }
	Point operator - (const Point &b) const {  return Point(x-b.x,y-b.y);  }
	int operator * (const Point &b) const {  return x*b.y-y*b.x;  }
	int len() const {  return x*x+y*y;  }
	int operator < (const Point &a) const
	{
		if((*this)*a>0 || (*this)*a==0 && len()<a.len())
			return 1;
		return 0;
	}
}Point;
int n;
Point s[122], p[122];
int dp[122][122];
int Jud(int m)
{
	int ans, i, j, now, k, flag, S;
	memset(dp, 0, sizeof(dp));
	ans = 0;
	for(i=2;i<=m;i++)
	{
		now = i-1;
		while(now>=1 && p[i]*p[now]==0)
			now--;
		flag = 0;
		if(now==i-1)
			flag = 1;
		while(now>=1)
		{
			S = p[now]*p[i];
			k = now-1;
			while(k>=1 && (p[now]-p[i])*(p[k]-p[now])>0)
				k--;
			if(k>=1)
				S += dp[now][k];
			if(flag)
				dp[i][now] = S;
			ans = max(ans, S);
			now = k;
		}
		if(flag==0)
			continue;
		for(j=1;j<=i-1;j++)
			dp[i][j] = max(dp[i][j],dp[i][j-1]);
	}
	return ans;
}
int main(void)
{
	int T, i, j, m, ans;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		for(i=1;i<=n;i++)
			scanf("%d%d", &s[i].x, &s[i].y);
		ans = 0;
		for(i=1;i<=n;i++)
		{
			m = 0;
			for(j=1;j<=n;j++)
			{
				if(s[j].y>s[i].y || s[j].y==s[i].y && s[j].x>=s[i].x)
					p[++m] = s[j]-s[i];
			}
			sort(p+1, p+m+1);
			ans = max(ans, Jud(m));
		}
		printf("%.1f\n", ans/2.0);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值