求凸包

BZOJ2829

#include <cstdio>
#include <algorithm>
#include <cmath>
#define LDB long double
using namespace std;

  const LDB eps=1e-8;

  struct data{
      LDB x,y,alp;
  }tmp[1000001],a[1000001],sta[1000010];

  int n,cnt;
  LDB xmini,ymini,bb,aa,r,ang[4],stddis;

  inline data operator - (const data&a,const data&b) {return (data){a.x-b.x,a.y-b.y,a.alp};}

  LDB X(data a,data b){
      return(a.x*b.y-a.y*b.x);
  }

  LDB dis(data a,data b){
      return(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
  }

  int mycomp(const data&aa,const data&b){
      if (aa.alp<b.alp-eps) return(1);
      if (aa.alp>b.alp+eps) return(0);
      return(dis(a[1],aa)>dis(a[1],b));
  }

  void makepoint(LDB x,LDB y,LDB ag){
      for (int i=0;i<4;i++){
        tmp[++cnt].x=x+stddis*cos(ang[i]+ag);
        tmp[cnt].y=y+stddis*sin(ang[i]+ag);
    }
  }

  int main(){
    freopen("a.in","r",stdin);
    freopen("wrong.out","w",stdout);

      scanf("%d",&n);
      scanf("%Lf%Lf%Lf",&bb,&aa,&r);aa-=2*r;bb-=2*r;
      ang[0]=atan2(bb,aa),ang[1]=atan2(bb,-aa),ang[2]=atan2(-bb,-aa),ang[3]=atan2(-bb,aa);
      stddis=sqrt(aa*aa/4+bb*bb/4);
      for (int i=1;i<=n;i++){
        LDB t1,t2,t3;
        scanf("%Lf%Lf%Lf",&t1,&t2,&t3);
      makepoint(t1,t2,t3);
    }
    n=4*n;

      xmini=1e9,ymini=1e9;
      int po;
      for (int i=1;i<=n;i++){
        if (ymini>tmp[i].y||(ymini==tmp[i].y&&tmp[i].x<xmini)){
          xmini=tmp[i].x;ymini=tmp[i].y;
          po=i;
      }
    }
    data t=tmp[po];tmp[po]=tmp[1];tmp[1]=t;
    for (int i=2;i<=n;i++) tmp[i].alp=atan2(tmp[i].y-ymini,tmp[i].x-xmini);
    a[1].x=xmini;a[1].y=ymini;
    sort(tmp+2,tmp+n+1,mycomp);

    cnt=1;
    tmp[1].alp=-1e9;
    for (int i=2;i<=n;i++)
      if (tmp[i].alp!=tmp[i-1].alp)
        a[++cnt]=tmp[i];
    n=cnt;    

    int top=0;
    for (int i=1;i<=n;i++){
      while (top>=2&&X(sta[top]-sta[top-1],a[i]-sta[top-1])<-eps)
        top--;
      sta[++top]=a[i];
    }

    LDB ans=acos(-1)*2*r;
    for (int i=1;i<=top;i++)
      ans+=dis(sta[i],sta[i%top+1]);
    printf("%.2Lf\n",ans);
  }
时间: 2024-10-12 21:31:34

求凸包的相关文章

poj2187 求平面最远点对,garham_scan算法求凸包

poj2187 求平面最远点对,garham_scan算法求凸包 Beauty Contest Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 29666   Accepted: 9180 Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'M

求凸包—— graham_scan算法

求凸包—— graham_scan算法 先按Y-X排序,在按对p0的极角排序,然后进行扫描 Point stk[maxn]; int top; bool cmpYX(const Point A,const Point B)//按Y-X排序 { if(A.y<B.y) return true; if(A.y==B.y){ return A.x<=B.x; } return false; } bool cmp(const Point A,const Point B)//按极角排序 { return

poj1113Wall 求凸包周长 Graham扫描法

#include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef pair<int ,int > ll; ll num,dot[1010]; int i; const double pi=3.1415926535898; ll operator -(ll a,ll b) { return make_pair(a.first-b.first,a.second-

Wall - POJ 1113(求凸包)

题目大意:给N个点,然后要修建一个围墙把所有的点都包裹起来,但是要求围墙距离所有的点的最小距离是L,求出来围墙的长度. 分析:如果没有最小距离这个条件那么很容易看出来是一个凸包,然后在加上一个最小距离L,那么就是在凸包外延伸长度为L,如下图,很明显可以看出来多出来的长度就是半径为L的圆的周长,所以总长度就是凸包的周长+半径为L的圆的周长. 代码如下: -------------------------------------------------------------------------

(hdu 7.1.7)Wall(求凸包的周长——求将所有点围起来的最小凸多边形的周长)

题目: Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 119 Accepted Submission(s): 47   Problem Description Once upon a time there was a greedy King who ordered his chief Architect to build a wa

(hdu step 7.1.7)Wall(求凸包的周长——求将全部点围起来的最小凸多边形的周长)

题目: Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 119 Accepted Submission(s): 47   Problem Description Once upon a time there was a greedy King who ordered his chief Architect to build a wa

HDU 4667 Building Fence(求凸包的周长)

A - Building Fence Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Description Long long ago, there is a famous farmer named John. He owns a big farm and many cows. There are two kinds of cows on his farm, o

POJ 1113 Wall 卷包裹法求凸包

Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31199   Accepted: 10521 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he w

求凸包(两遍扫描,求上下凸包的方法)

求凸包模版 struct point { double x,y; double val,len; }points[20]; point points1[20]; point points2[20]; const int INF=1e8; bool cmp(point a,point b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } double chaji(point a,point b,point c,point d) { return

Wall--POJ1113(极角排序+求凸包)

http://poj.org/problem?id=1113 题目大意:现在要给n个点,让你修一个围墙把这些点围起来,距离最小是l 分析  :现在就是求凸包的周长然后再加上一个圆的周长 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> #include<iostream> #include<qu