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;
}