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;
    }
     
  • 相关阅读:
    Linux文件查询笔记
    C语言学习和回顾
    hive的数据压缩
    进程线程那些事儿
    hive的数据存储格式
    hive的内置函数
    Hive自定义函数
    spark编译
    Impala的安装和使用
    数据库的读写分离
  • 原文地址:https://www.cnblogs.com/hyfer/p/11655962.html
Copyright © 2011-2022 走看看