zoukankan      html  css  js  c++  java
  • POJ 3246 Game(凸包)

    【题目链接】 http://poj.org/problem?id=3246

    【题目大意】

      给出一些点,请删去一个点,使得包围这些点用的线长最短

    【题解】

      去掉的点肯定是凸包上的点,所以枚举凸包上的点去掉,再计算面积即可。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <cstring>
    using namespace std;
    struct P{
        int x,y;
        int id;
        P(){}
        P(double x,double y):x(x),y(y){}
        P operator + (P p){return P(x+p.x,y+p.y);}
        P operator - (P p){return P(x-p.x,y-p.y);}
        P operator * (double d){return P(x*d,y*d);}
        int dot(P p){return x*p.x+y*p.y;} //点积
        int det(P p){return x*p.y-y*p.x;}  //叉积
    };
    bool cmp_x(const P& p,const P& q){
        if(p.x!=q.x)return p.x<q.x;
        return p.y<q.y;  
    }
    vector<P> convex_hull(P* ps,int n){
        sort(ps,ps+n,cmp_x);
        int k=0;
        vector<P> qs(n*2);
        for(int i=0;i<n;i++){
            while((k>1)&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0)k--;
            qs[k++]=ps[i];
        }
        for(int i=n-2,t=k;i>=0;i--){
            while(k>t&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0)k--;
            qs[k++]=ps[i];
        }qs.resize(k-1);
        return qs;
    }
    int cross(P a, P b,P c){return(b-a).det(c-a);}
    int compute_area(P A,P B,P C){
        int res=cross(A,B,C);
        if(res<0){return -res;}
        return res;
    }
    int compute_area(const vector<P>& ps){
        int total=0;
        for(int i=2;i<ps.size();i++){
            total+=compute_area(ps[0],ps[i-1],ps[i]);
        }return total;
    }
    const int MAX_N=100010;
    int N;
    P p[MAX_N],q[MAX_N];
    void solve(){
        for(int i=0;i<N;i++){
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].id=i;
        }memcpy(q,p,N*sizeof(P));
        vector<P> ps=convex_hull(p,N);
        int ans=0x3f3f3f3f;
        for(int i=0;i<ps.size();i++){
            memcpy(p,q,N*sizeof(P));
            swap(p[ps[i].id],p[N-1]);
            ans=min(ans,compute_area(convex_hull(p,N-1)));
        }printf("%d.%s
    ",ans/2,ans%2==1?"50":"00");
    }
    int main(){
        while(~scanf("%d",&N),N)solve();
        return 0;
    }
  • 相关阅读:
    [贪心经典算法]Kruskal算法
    [经典贪心算法]Prim算法
    Java容器之List接口
    Java容器之Set接口
    JDK中的泛型
    Java中ArrayList与数组间相互转换
    Java中的增强for循环
    Java容器之Iterator接口
    Java之容器
    eg_4
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3246.html
Copyright © 2011-2022 走看看