zoukankan      html  css  js  c++  java
  • ●POJ 1873 The Fortified Forest

    题链:

    http://poj.org/problem?id=1873

    题解:

    计算几何,凸包

    枚举被砍的树的集合。求出剩下点的凸包。然后判断即可。

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=16,INF=0x3f3f3f3f;
    const double eps=1e-8;
    int sign(double x){
    	if(fabs(x)<=eps) return 0;
    	return x<0?-1:1;
    }
    struct Point{
    	double x,y;
    	Point(double _x=0,double _y=0):x(_x),y(_y){}
    	void Read(){scanf("%lf%lf",&x,&y);}
    }D[MAXN],H[MAXN];
    typedef Point Vector;
    bool operator < (Point A,Point B){return sign(A.x-B.x)<0||(sign(A.x-B.x)==0&&sign(A.y-B.y)<0);}
    bool operator == (Point A,Point B){return sign(A.x-B.x)==0&&sign(A.y-B.y)==0;}
    Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
    double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
    double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
    int V[MAXN],N,ansS,ansV,ansN;
    double L[MAXN],resL;
    double GL(Vector A){//Get_Length
    	return sqrt(A*A);
    }
    int Andrew(int S){
    	int hnt=0,k=0,tnt=0;
    	static Point tmp[MAXN];
    	for(int i=1;i<=N;i++) if(!(S&(1<<(i-1)))) tmp[++tnt]=D[i];
    	sort(tmp+1,tmp+tnt+1);
    	tnt=unique(tmp+1,tmp+tnt+1)-tmp-1;
    	for(int i=1;i<=tnt;i++){
    		while(hnt>1&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
    		H[++hnt]=tmp[i];
    	} k=hnt;
    	for(int i=tnt-1;i>=1;i--){
    		while(hnt>k&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
    		H[++hnt]=tmp[i];
    	}
    	return hnt;
    }
    double GCPC(int hnt){//Get_Convex_Polygon_Circumference	
    	double C=0;
    	for(int i=1;i<hnt;i++) C+=GL(H[i+1]-H[i]);
    	return C;
    }
    int main(){
    	double C,nowL;
    	int nowS,nowV,nowN,Case=0;
    	while(scanf("%d",&N)&&N){
    		if(N==0) break;
    		ansS=(1<<N)-1; ansV=INF; ansN=N; resL=0;
    		for(int i=1;i<=N;i++)
    			D[i].Read(),scanf("%d%lf",&V[i],&L[i]);
    		for(int S=1;S<=(1<<N)-1;S++){
    			nowS=S; nowN=0; nowL=0; nowV=0;
    			for(int i=1;i<=N;i++) if(S&(1<<(i-1)))
    				nowN++,nowV+=V[i],nowL+=L[i];
    			C=GCPC(Andrew(S));
    			if(sign(nowL-C)<0) continue;
    			if(nowV<ansV||(nowV==ansV&&nowN<ansN))
    				ansS=nowS,ansV=nowV,ansN=nowN,resL=nowL-C;
    		}
    		if (Case) puts(""); 		
    		printf("Forest %d
    ",++Case);
    		printf("Cut these trees:");
    		for(int i=1;i<=N;i++) if(ansS&(1<<(i-1))) printf(" %d",i);
    		printf("
    Extra wood: %.2lf
    ",resL);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    HelpersRainCaptcha
    HelpersPHPMailer
    HelpersPassword
    HelpersPagination
    HelpersNumber
    HelpersHooks
    HelpersGeoCode
    HelpersFastCache
    HelpersDocument
    eclipse 设置jsp页面为HTML5
  • 原文地址:https://www.cnblogs.com/zj75211/p/8227646.html
Copyright © 2011-2022 走看看