zoukankan      html  css  js  c++  java
  • Wall POJ

    要求包围所有n个点并且距所有点距离大于L的多边形周长

    这个多边形的周长可以通过凸包上的边做平移加上一个半径L的圆辅助转向得到

    所以就是求凸包周长加上圆周长

    主要是为了试试凸包的接口,实现用的是Graham,应该是单调栈吧?

    //#include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
      
    const double pi=acos(-1.0);  
    #define ll long long  
    #define pb push_back  
     
    const int maxn=1e3+56;
    
    const double eps=1e-6;  
     
    int sgn(double x){  
        if(fabs(x)<eps)return 0;  
        if(x<0)return -1;  
        else return 1;  
    }  
      
    struct Point{  
        double x,y;  
    	void input(){
    		scanf("%lf%lf",&x,&y);
    	}
        Point(){}  
        Point(double _x,double _y){x=_x;y=_y;}  
        double distance(Point p){  
            return hypot(x-p.x,y-p.y);  
        }  
        Point operator +(const Point &b)const{  
            return Point(x+b.x,y+b.y);  
        }  
        Point operator -(const Point &b)const{  
            return Point(x-b.x,y-b.y);  
        }  
        double operator *(const Point &b)const{  
            return x*b.x+y*b.y;  
        }  
        Point operator *(const double &k)const{  
            return Point(x*k,y*k);  
        }  
        Point operator /(const double &k)const{  
            return Point(x/k,y/k);  
        }  
        double operator^(const Point &b)const{  
            return x*b.y-y*b.x;  
        }  
    	bool operator ==(Point b)const{
    		return sgn(x-b.x)==0 && sgn(y-b.y)==0;
    	}
    	bool operator < (Point b)const{
    		return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;
    	}
        double len(){return hypot(x,y);}  
        double len2(){  
            return x*x+y*y;  
        }  
        Point trunc(double r){  
            double l=len();  
            if(!sgn(l))return *this;  
            r/=l;  
            return Point(x*r,y*r);  
        }  
    };  
      
    struct Line{  
        Point s,e;  
        Line(){}  
        Line (Point _s,Point _e){  
            s=_s;e=_e;  
        }  
        Line(Point p,double angle){//与x轴夹角  
            s=p;  
            if(sgn(angle-pi/2)==0)e=(s+Point(0,1));  
            else e=(s+Point(1,tan(angle)));  
        }  
        double length(){return s.distance(e);}  
        double dispointtoline(Point p){  
            return fabs((p-s)^(e-s))/length();  
        }  
        double dispointtoseg(Point p){  
            if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)  
                return min(p.distance(s),p.distance(e));  
            return dispointtoline(p);  
        }  
        Point lineprog(Point p){  
            return s+( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );  
        }  
    };
    
    struct polygon{
    	int n;
    	Point p[maxn];
    	Line l[maxn];
    	void input(int _n){
    		n=_n;for(int i=0;i<n;i++)p[i].input();
    	}
    	void add(Point q){p[n++]=q;};
    	void getline(){
    		for(int i=0;i<n;i++){
    			l[i]=Line(p[i],p[(i+1)%n]);
    		}
    	}
    	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 mi=p[0];
    		for(int i=1;i<n;i++)mi=min(mi,p[i]);
    		sort(p,p+n,cmp(mi));
    	}
    	void Graham(polygon &convex){
    		norm();
    		int &top=convex.n;
    		top=0;
    		if(n==1){
    			top=1;convex.p[0]=p[0];
    			return;
    		}
    		if(n==2){
    			top=2;convex.p[0]=p[0];convex.p[1]=p[1];
    			if(convex.p[0]==convex.p[1])top--;return;
    		}
    		convex.p[0]=p[0];
    		convex.p[1]=p[1];
    		top=2;
    		for(int i=2;i<n;i++){
    			while(top>1 && sgn((convex.p[top-1]-convex.p[top-2])^
    					(p[i]-convex.p[top-2]))<=0)top--;
    			convex.p[top++]=p[i];
    		}
    		if(convex.n==2 && (convex.p[0]==convex.p[1]))convex.n--;
    	}
    	double getcircumference(){
    		double sum=0;
    		for(int i=0;i<n;i++)sum+=p[i].distance(p[(i+1)%n]);
    		return sum;
    	}
    };
    
    int main(){
    	int n,r;
    	while(~scanf("%d%d",&n,&r)){
    		polygon now;
    		now.input(n);
    		polygon convex;
    		now.Graham(convex);
    		printf("%d
    ",(int)round(convex.getcircumference()+pi*2*r));
    	}
    }


    贴一个不用kb模板的轻量化板子:

    //#include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
      
    const double pi=acos(-1.0);  
    #define ll long long  
    #define pb push_back
    
    #define sqr(a) ((a)*(a))
    #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    
    const int maxn=1e3+56;
    const int inf=0x3f3f3f3f;
    
    struct Point{
    	double x,y;
    	int v,l;
    	Point(double a=0,double b=0){x=a;y=b;}
    	bool operator<(Point b)const{
    		return y<b.y||(y==b.y && x<b.x);
    	}
    }p[maxn],ch[maxn<<1],tmp[maxn];
    
    double mult(Point a,Point b,Point o){
    	return(a.x-o.x)*(b.y-o.y)>=(b.x-o.x)*(a.y-o.y);
    }
    
    double Graham(Point p[],int n,Point res[]){	//返回凸包周长
    	int top=1;
    	sort(p,p+n);
    	if(n==0)return 0;res[0]=p[0];
    	if(n==1)return 0;res[1]=p[1];
    	if(n==2)return dis(p[0],p[1])*2;
    	res[2]=p[2];
    	for(int i=2;i<n;i++){
    		while(top && (mult(p[i],res[top],res[top-1])))
    			top--;
    		res[++top]=p[i];
    	}
    	int len=top;
    	res[++top]=p[n-2];
    	for(int i=n-3;i>=0;i--){
    		while(top!=len && (mult(p[i],res[top],res[top-1])))
    			top--;
    		res[++top]=p[i];
    	}
    	double c=dis(res[0],res[top-1]);
    	for(int i=0;i<top-1;i++){
    		c+=dis(res[i],res[i+1]);
    	}
    	return c;
    }
    
    int n,kase;
    
    int main(){
    	while(scanf("%d",&n)&&n){
    		for(int i=0;i<n;i++){
    			scanf("%lf%lf%d%d",&p[i].x,&p[i].y,&p[i].v,&p[i].l);
    		}
    		int min_cut=inf,min_val=inf,ans=0;
    		double res_len=0;
    
    		for(int bit=0;bit<(1<<n);bit++){
    			int res=0,cut_val=0;
    			double cut_len=0;
    
    			for(int i=0;i<n;i++){
    				if(bit & (1<<i)){
    					cut_len+=p[i].l;
    					cut_val+=p[i].v;
    				}else{
    					tmp[res].x=p[i].x;
    					tmp[res++].y=p[i].y;
    				}
    			}
    			if(cut_val>min_val)continue;
    			double c=Graham(tmp,res,ch);
    			if(cut_len>=c){
    				if(cut_val<min_val || (cut_val==min_val && n-res<min_cut)){
    					ans=bit;
    					min_val=cut_val;
    					min_cut=n-res;
    					res_len=cut_len-c;
    				}
    			}
    		}
    		if(kase)puts("");
    		printf("Forest %d
    ",++kase);
    		printf("Cut these trees:");
    		for(int i=0;i<n;i++)
    			if(ans&(1<<i))
    				printf(" %d",i+1);
    		printf("
    Extra wood: %.2f
    ",res_len);
    	}
    }
    


  • 相关阅读:
    【好文翻译】10个免费的压力测试工具(Web)
    【高手介绍】谷歌内部代码审查(code review)介绍[翻译]
    【淘宝内部好文转发】我们每天面对的互联网用户到底在想什么?
    写给开发者:别让他人用你的App赚钱[转]
    新手应该知道的二十三条关于JavaScript的最佳实践
    开发人员应该为这样的代码感到惭愧
    [Web App]必胜客宅急送产品设计思路介绍[转]
    WallsEveryDay 必应桌面壁纸
    GroupLayout 布局
    JButton 做图片框
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611247.html
Copyright © 2011-2022 走看看