Wall POJ - 1113 凸包模板

要求包围所有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\n",(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\n",++kase);
		printf("Cut these trees:");
		for(int i=0;i<n;i++)
			if(ans&(1<<i))
				printf(" %d",i+1);
		printf("\nExtra wood: %.2f\n",res_len);
	}
}


posted @ 2017-09-24 02:28  Drenight  阅读(196)  评论(0编辑  收藏  举报