zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    New version of VS2005 extensions for SharePoint 3.0
    QuickPart : 用户控件包装器 for SharePoint Server 2007
    随想
    发布 SharePoint Server 2007 Starter Page
    如何在SharePoint Server中整合其他应用系统?
    Office SharePoint Server 2007 中文180天评估版到货!
    RMS 1.0 SP2
    SharePoint Server 2007 Web内容管理中的几个关键概念
    如何为已存在的SharePoint站点启用SSL
    Some update information about Office 2007
  • 原文地址:https://www.cnblogs.com/hyfer/p/11655962.html
Copyright © 2011-2022 走看看