hdu 6219 Empty Convex Polygons (凸包)

给你n个点,求面积最大的凸多边形,使得这个凸多边形没有内点。
考虑求凸包的graham算法,需要找到左下角的点,再进行极角排序后按顺序扫点,所以先枚举左下角的点。
这个过程中,如果遇到内点,就需要把这个内点排除掉,而现在需要把在外的点排除掉。
因为不确定凸包的边界,需要dp处理,一开始是一个三角线的两条边作为边界,然后不断枚举可能的边界进行扩展,同时保证不能包含内点。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define lson l,m,rt<<1
#define pi acos(-1)
#define rson m+1,r,rt<<1|1
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define eps 3e-11
using namespace std;
const int maxn = 55;
const ll inf = 1e9;
const ll mod = 998244353;
ll read() {
    ll x=0,f=1;
    char ch=getchar();
    while(!(ch>='0'&&ch<='9')) {
        if(ch=='-')f=-1;
        ch=getchar();
    };
    while(ch>='0'&&ch<='9') {
        x=x*10+(ch-'0');
        ch=getchar();
    };
    return x*f;
}
int sgn(double x){
    if(fabs(x)<eps)return 0;
    if(x<0)return -1;
    return 1;
}
struct Point{
    int id;
    double x,y;
    Point(){
    }
    Point(double _x,double _y){
        x=_x;
        y=_y;
    }
    friend bool operator < (Point a,Point b) {
        return sgn(a.x-b.x)==0?sgn(a.y-b.y)<0:a.x<b.x;
    }
    double operator ^ (const Point &b) const{
        return x*b.y - y*b.x;
    }
    bool operator == (const Point &b) const{
        return sgn(x-b.x)==0&&sgn(y-b.y)==0;
    }
    Point operator - (const Point &b) const{
        return Point(x-b.x,y-b.y);
    }
    double distance(Point b){
        return sqrt((x-b.x)*(x-b.x) + (y-b.y)*(y-b.y));
    }
};
struct polygon{
    int n;
    Point p[maxn];
    struct cmp{
        Point p;
        cmp(const Point &p0) {p=p0;}
        bool operator()(const Point &aa,const Point &bb){
            Point a=aa,b=bb;
            int d=sgn((a-p)^(b-p));
            if(d==0){
                return sgn(a.distance(p) - b.distance(p)) < 0;
            }
            return d>0;
        }
    };
    void norm(Point t){
        sort(p+1,p+1+n,cmp(t));
    }
    int relationpoint(Point q){
        int cnt = 0;
        fo(i,0,n-1){
            int j = (i+1)%n;
            int k = sgn((q-p[j])^(p[i]-p[j]));
            int u = sgn(p[i].y-q.y);
            int v = sgn(p[j].y-q.y);
            if(k>0&&u<0&&v>=0)cnt++;
            if(k<0&&v<0&&u>=0)cnt--;
            if(k==0)return 2;
        }
        return cnt != 0;
    }
}ps,pts,rec;
int n;
bool ok[maxn][maxn][maxn];
double dp[maxn][maxn],ans;
void gao(int st){
    memset(dp,0,sizeof(dp));
    int m = n-st+1;
    pts.n=m;
    fo(i,1,m){
        pts.p[i] = ps.p[st+i-1];
    }
    pts.norm(pts.p[1]);
    fo(i,2,m){
        fo(j,i+1,m){
            if(!ok[pts.p[1].id][pts.p[i].id][pts.p[j].id]){
                dp[i][j] = 0;
            }else{
                bool flag = true;
                fo(k,2,i-1){
                    if(sgn((pts.p[k]-pts.p[1])^(pts.p[i]-pts.p[1]))==0){
                        flag=false;
                        break;
                    }
                }
                if(flag)fo(k,2,i-1){
                    if(sgn((pts.p[i]-pts.p[k])^(pts.p[j]-pts.p[i]))>=0){

                        dp[i][j] = max(dp[i][j],dp[k][i]);
                    }
                }
                dp[i][j] += ((pts.p[i]-pts.p[1]) ^ (pts.p[j]-pts.p[1]))/2.0;
            }
            ans=max(ans,dp[i][j]);
        }
    }
}
int main() {
    int T=read();
    while(T--){
        ans=0;
        n=ps.n=read();
        fo(i,1,n){
            ps.p[i] = Point(read(),read());
        }
        sort(ps.p+1,ps.p+1+n);
        fo(i,1,n) ps.p[i].id=i;
        fo(i,1,n){
            fo(j,i+1,n){
                fo(k,j+1,n){
                    rec.n=3;
                    rec.p[0]=ps.p[i];rec.p[1]=ps.p[j];rec.p[2]=ps.p[k];
                    ok[k][i][j]=ok[k][j][i]=ok[j][i][k]=ok[j][k][i]=ok[i][k][j]=ok[i][j][k]=true;
                    if(sgn((rec.p[1]-rec.p[0])^(rec.p[2]-rec.p[0]))==0)continue;
                    fo(t,1,n){
                        if(t==i||t==j||t==k)continue;
                        if(rec.relationpoint(ps.p[t])==1){
                            ok[k][i][j]=ok[k][j][i]=ok[j][i][k]=ok[j][k][i]=ok[i][k][j]=ok[i][j][k]=false;
                            break;
                        }
                    }
                }
            }
        }
        fo(i,1,n){
            gao(i);
        }
        printf("%.1f\n",ans);
    }
    return 0;
}

 

 
posted @ 2019-10-11 18:20  ACforever  阅读(356)  评论(0编辑  收藏  举报