result=对所有点凸包周长+pi*2*L

WA了一次,被Pi的精度坑了

以后注意Pi尽可能搞精确一点。Pi=3.14还是不够用

Code:

  1 #include<vector>
  2 #include<list>
  3 #include<map>
  4 #include<set>
  5 #include<deque>
  6 #include<queue>
  7 #include<stack>
  8 #include<bitset>
  9 #include<algorithm>
 10 #include<functional>
 11 #include<numeric>
 12 #include<utility>
 13 #include<iostream>
 14 #include<sstream>
 15 #include<iomanip>
 16 #include<cstdio>
 17 #include<cmath>
 18 #include<cstdlib>
 19 #include<cctype>
 20 #include<string>
 21 #include<cstring>
 22 #include<cstdio>
 23 #include<cmath>
 24 #include<cstdlib>
 25 #include<ctime>
 26 #include<climits>
 27 #include<complex>
 28 #define mp make_pair
 29 #define pb push_back
 30 using namespace std;
 31 const double eps=1e-8;//精度
 32 const double pi=acos(-1.0);//π
 33 const double inf=1e20;//无穷大
 34 const int maxp=1111;//最大点数
 35
 36 /*
 37     判断d是否在精度内等于0
 38 */
 39 int dblcmp(double d)
 40 {
 41     if (fabs(d)<eps)return 0;
 42     return d>eps?1:-1;
 43 }
 44 /*
 45     求x的平方
 46 */
 47 inline double sqr(double x){return x*x;}
 48 /*
 49     点/向量
 50 */
 51 struct point
 52 {
 53     double x,y;
 54     point(){}
 55     point(double _x,double _y):x(_x),y(_y){};
 56     //读入一个点
 57     void input()
 58     {
 59         scanf("%lf%lf",&x,&y);
 60     }
 61     //输出一个点
 62     void output()
 63     {
 64         printf("%.2f %.2f\n",x,y);
 65     }
 66     //判断两点是否相等
 67     bool operator==(point a)const
 68     {
 69         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
 70     }
 71     //判断两点大小
 72     bool operator<(point a)const
 73     {
 74         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
 75     }
 76     //点到源点的距离/向量的长度
 77     double len()
 78     {
 79         return hypot(x,y);
 80     }
 81     //点到源点距离的平方
 82     double len2()
 83     {
 84         return x*x+y*y;
 85     }
 86     //两点间的距离
 87     double distance(point p)
 88     {
 89         return hypot(x-p.x,y-p.y);
 90     }
 91     //向量加
 92     point add(point p)
 93     {
 94         return point(x+p.x,y+p.y);
 95     }
 96     //向量减
 97     point sub(point p)
 98     {
 99         return point(x-p.x,y-p.y);
100     }
101     //向量乘
102     point mul(double b)
103     {
104         return point(x*b,y*b);
105     }
106     //向量除
107     point div(double b)
108     {
109         return point(x/b,y/b);
110     }
111     //点乘
112     double dot(point p)
113     {
114         return x*p.x+y*p.y;
115     }
116     //叉乘
117     double det(point p)
118     {
119         return x*p.y-y*p.x;
120     }
121     //XXXXXXX
122     double rad(point a,point b)
123     {
124         point p=*this;
125         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
126     }
127     //截取长度r
128     point trunc(double r)
129     {
130         double l=len();
131         if (!dblcmp(l))return *this;
132         r/=l;
133         return point(x*r,y*r);
134     }
135     //左转90度
136     point rotleft()
137     {
138         return point(-y,x);
139     }
140     //右转90度
141     point rotright()
142     {
143         return point(y,-x);
144     }
145     //绕点p逆时针旋转angle角度
146     point rotate(point p,double angle)
147     {
148         point v=this->sub(p);
149         double c=cos(angle),s=sin(angle);
150         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
151     }
152 };
153 /*
154     线段/直线
155 */
156 struct line
157 {
158     point a,b;
159     line(){}
160     line(point _a,point _b)
161     {
162         a=_a;
163         b=_b;
164     }
165     //判断线段相等
166     bool operator==(line v)
167     {
168         return (a==v.a)&&(b==v.b);
169     }
170     //点p做倾斜角为angle的射线
171     line(point p,double angle)
172     {
173         a=p;
174         if (dblcmp(angle-pi/2)==0)
175         {
176             b=a.add(point(0,1));
177         }
178         else
179         {
180             b=a.add(point(1,tan(angle)));
181         }
182     }
183     //直线一般式ax+by+c=0
184     line(double _a,double _b,double _c)
185     {
186         if (dblcmp(_a)==0)
187         {
188             a=point(0,-_c/_b);
189             b=point(1,-_c/_b);
190         }
191         else if (dblcmp(_b)==0)
192         {
193             a=point(-_c/_a,0);
194             b=point(-_c/_a,1);
195         }
196         else
197         {
198             a=point(0,-_c/_b);
199             b=point(1,(-_c-_a)/_b);
200         }
201     }
202     //读入一个线段
203     void input()
204     {
205         a.input();
206         b.input();
207     }
208     //校准线段两点
209     void adjust()
210     {
211         if (b<a)swap(a,b);
212     }
213     //线段长度
214     double length()
215     {
216         return a.distance(b);
217     }
218     //直线倾斜角 0<=angle<180
219     double angle()
220     {
221         double k=atan2(b.y-a.y,b.x-a.x);
222         if (dblcmp(k)<0)k+=pi;
223         if (dblcmp(k-pi)==0)k-=pi;
224         return k;
225     }
226     //点和线段关系
227     //1 在逆时针
228     //2 在顺时针
229     //3 平行
230     int relation(point p)
231     {
232         int c=dblcmp(p.sub(a).det(b.sub(a)));
233         if (c<0)return 1;
234         if (c>0)return 2;
235         return 3;
236     }
237     //点是否在线段上
238     bool pointonseg(point p)
239     {
240         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
241     }
242     //两线是否平行
243     bool parallel(line v)
244     {
245         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
246     }
247     //线段和线段关系
248     //0 不相交
249     //1 非规范相交
250     //2 规范相交
251     int segcrossseg(line v)
252     {
253         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
254         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
255         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
256         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
257         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
258         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
259                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
260                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
261                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
262     }
263     //线段和直线v关系
264     int linecrossseg(line v)//*this seg v line
265     {
266         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
267         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
268         if ((d1^d2)==-2)return 2;
269         return (d1==0||d2==0);
270     }
271     //直线和直线关系
272     //0 平行
273     //1 重合
274     //2 相交
275     int linecrossline(line v)
276     {
277         if ((*this).parallel(v))
278         {
279             return v.relation(a)==3;
280         }
281         return 2;
282     }
283     //求两线交点
284     point crosspoint(line v)
285     {
286         double a1=v.b.sub(v.a).det(a.sub(v.a));
287         double a2=v.b.sub(v.a).det(b.sub(v.a));
288         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
289     }
290     //点p到直线的距离
291     double dispointtoline(point p)
292     {
293         return fabs(p.sub(a).det(b.sub(a)))/length();
294     }
295     //点p到线段的距离
296     double dispointtoseg(point p)
297     {
298         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
299         {
300             return min(p.distance(a),p.distance(b));
301         }
302         return dispointtoline(p);
303     }
304     //XXXXXXXX
305     point lineprog(point p)
306     {
307         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
308     }
309     //点p关于直线的对称点
310     point symmetrypoint(point p)
311     {
312         point q=lineprog(p);
313         return point(2*q.x-p.x,2*q.y-p.y);
314     }
315 };
316
317 /*
318     多边形
319 */
320 struct polygon
321 {
322     int n;//点个数
323     point p[maxp];//顶点
324     //读入一个多边形
325     void input(int n)
326     {
327         for (int i=0;i<n;i++)
328         {
329             p[i].input();
330         }
331     }
332     struct cmp
333     {
334         point p;
335         cmp(const point &p0){p=p0;}
336         bool operator()(const point &aa,const point &bb)
337         {
338             point a=aa,b=bb;
339             int d=dblcmp(a.sub(p).det(b.sub(p)));
340             if (d==0)
341             {
342                 return dblcmp(a.distance(p)-b.distance(p))<0;
343             }
344             return d>0;
345         }
346     };
347     void norm()
348     {
349         point mi=p[0];
350         for (int i=1;i<n;i++)mi=min(mi,p[i]);
351         sort(p,p+n,cmp(mi));
352     }
353     //求凸包存入多边形convex
354     void getconvex(polygon &convex)
355     {
356         int i,j,k;
357         sort(p,p+n);
358         convex.n=n;
359         for (i=0;i<min(n,2);i++)
360         {
361             convex.p[i]=p[i];
362         }
363         if (n<=2)return;
364         int &top=convex.n;
365         top=1;
366         for (i=2;i<n;i++)
367         {
368             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
369                 top--;
370             convex.p[++top]=p[i];
371         }
372         int temp=top;
373         convex.p[++top]=p[n-2];
374         for (i=n-3;i>=0;i--)
375         {
376             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
377                 top--;
378             convex.p[++top]=p[i];
379         }
380     }
381     //取得周长
382     double getcircumference()
383     {
384         double sm=0;
385         int i;
386         for (i=0;i<n;i++)
387         {
388             sm+=p[i].distance(p[(i+1)%n]);
389             //printf("%.2f\n",sm);
390         }
391         return sm;
392     }
393 };
394
395 struct polygon P,R;
396 int N,L;
397 double sum=0;
398
399 int main()
400 {
401     //freopen("in2.txt","r",stdin);
402
403     cin>>N>>L;
404     P.n=N;
405     P.input(N);
406     P.getconvex(R);
407
408     sum=R.getcircumference();
409     //cout<<R.n<<endl;
410     //for (int i=0;i<R.n;i++)
411     //    printf("%.2f %.2f\n",R.p[i].x,R.p[i].y);
412
413     sum+=3.14159265358979723846*(double)L*2;
414     printf("%.0f\n",sum);
415
416     return 0;
417 }

View Code

最基础的凸包算法:卷包裹算法。基本思想就好像把所有的点比作一堆钉子,拿一根绳子捆在最左边的点上,然后按顺时针or逆时针围一圈

http://www.cnblogs.com/Booble/archive/2011/02/28/1967179.html

------------------------我是傲傲傲娇哒分割线---------------------------------

求凸包的Andrew算法:

设所有点在平面坐标系上,从最左下角的点开始,从左到右来一次,再从右到左来一次,最后回到起点。

把所有点按x和y坐标作为关键字从小到大排序(x优先)。先把第一个点和第二个点加入凸包。

在扫描的过程中,当前凸包的前进方向即倒数第二个入凸包的点->倒数第一个入凸包的点这一向量。

若新点在凸包前进方向的左边则继续,否则依次删除最近加入凸包的点,直到新点在左边为止。

eg:

STEP1:当前已经加入了这些点:

STEP2:加入了点4

STEP3:这时再想加5的时候发现5在向量3->4的右边,加不了了-_-||

     于是把4删掉。

STEP4:这时5在向量2->3的左边了。加5

    PS:如果删掉了还是在右边的话就接着删

判断新点在某个向量的左边还是右边可以用叉乘。

转载于:https://www.cnblogs.com/pdev/p/4236735.html

poj1113 凸包相关推荐

  1. 【POJ1113】Wall(凸包)

    [题目] Description Once upon a time there was a greedy King who ordered his chief Architect to build a ...

  2. poj1113/hdu1348(凸包。。。两个网站上的输入输出有点出入)

    Wall Once upon a time there was a greedy King who ordered his chief Architect to build a wall around ...

  3. Graham Scan凸包算法

    获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...

  4. 旋转卡壳凸包(不用一下子就学完所有)

    目录 前言 参考博客 前置知识 1.极角排序 2.凸包(默认逆时针) 3.对踵点 旋转卡壳能解决的各类问题 1.计算距离 1.1凸多边形直径 1.2凸多边形宽 1.3凸多边形间最大距离 1.4凸多边形 ...

  5. 分治法解决凸包问题(快包)

    假设集合 S S S是平面上 n > 1 n>1 n>1个点 p 1 ( x 1 , y 1 ) , . . . , p n ( x n , y n ) p_1(x_1,y_1),. ...

  6. 《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(二)寻找物体的凸包

    8.2 寻找物体的凸包 8.2.1 概念 1.给定二维平面上的点集,将最外层点连接起来构成的凸多边形. 2.理解物体形状或轮廓的一种比较有用的方法是计算一个物体的凸包,然后计算其凸缺陷(convexi ...

  7. 写到usaco上的一题可能题解是凸包所以转来这篇文章看看

    凸包 graham 算法 标签: 算法distancexpstructoutputinput 2011-09-08 12:30 8371人阅读 评论(2) 收藏 举报  分类: c++ 凸包 grah ...

  8. UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP

    题目链接 UOJ #7 题解 首先这一定是DP!可以写出: \[f[i] = \min_{ancestor\ j} \{f[j] + (d[j] - d[i]) * p[i] + q[i]\}\] 其 ...

  9. 【OpenCV 】计算物体的凸包/创建包围轮廓的矩形和圆形边界框/createTrackbar添加滑动条/

    目录 topic 1:模板匹配 topic 2:图像中寻找轮廓 topic 3:计算物体的凸包 topic 4:轮廓创建可倾斜的边界框和椭圆¶ topic 5:轮廓矩¶ topic 6:为程序界面添加 ...

  10. HDU1392(凸包求周长模版)

    其实这个求凸包周长也算是模版. #include<iostream> #include<algorithm> #include<cstring> #include& ...

最新文章

  1. Android类库打包方法探究
  2. 通过Navicat for MySQL远程连接的时候报错mysql 1130的解决方法
  3. tensorflow1
  4. block为什么用copy以及如何解决循环引用
  5. 【机器学习】Logistic Regression 的前世今生(理论篇)
  6. python的进程模块
  7. 优化案例(part7)--Latent Multi-view Subspace Clustering
  8. linux 版本_Linux动态库版本号作用机制
  9. Activiti5第十一弹,流程监听器与任务监听器
  10. 求┐(P双向Q)∧(┐P蕴含R)的主析取范式、主合取范式
  11. http服务ajax编程
  12. 现在,TensorRT 4开放下载了
  13. ARM上的Bootloader的具体实现1071098736
  14. [转]html控件、html服务器控件和web服务器控件的区别
  15. C++入门经典-例8.8-虚继承
  16. Hibernate下载和安装
  17. 金字塔原理——表达的逻辑
  18. 全连接简单minist操作
  19. git pull报错 Can‘t update no tracked branch
  20. ffi一些常见的错误

热门文章

  1. Android ANR原因以及开发时如何预防
  2. 设计模式--单例模式(二)双重校验锁模式
  3. 国内物联网平台初探(五) ——机智云IoT物联网云服务平台及智能硬件自助开发平台...
  4. 【原创】Nginx+PHP-FPM优化技巧总结
  5. TrackMouseEvent 与_TrackMouseEvent
  6. (转帖)無號數及有號數的乘加運算電路設計(Verilog)
  7. 首张牌照花落“东方购物” 或抬高电视购物门槛
  8. 员工收“老板”QQ消息转账98万 警方挽回被骗资金
  9. 在centos上安装nginx
  10. 客户端工具收取邮件提示-ERR maildrop alredy locked