Wall POJ

来源:互联网 发布:想做淘宝客服兼职 编辑:程序博客网 时间:2024/05/23 09:43

要求包围所有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);}}