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

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

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

Code:

 #include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<climits>
#include<complex>
#define mp make_pair
#define pb push_back
using namespace std;
const double eps=1e-;//精度
const double pi=acos(-1.0);//π
const double inf=1e20;//无穷大
const int maxp=;//最大点数 /*
判断d是否在精度内等于0
*/
int dblcmp(double d)
{
if (fabs(d)<eps)return ;
return d>eps?:-;
}
/*
求x的平方
*/
inline double sqr(double x){return x*x;}
/*
点/向量
*/
struct point
{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){};
//读入一个点
void input()
{
scanf("%lf%lf",&x,&y);
}
//输出一个点
void output()
{
printf("%.2f %.2f\n",x,y);
}
//判断两点是否相等
bool operator==(point a)const
{
return dblcmp(a.x-x)==&&dblcmp(a.y-y)==;
}
//判断两点大小
bool operator<(point a)const
{
return dblcmp(a.x-x)==?dblcmp(y-a.y)<:x<a.x;
}
//点到源点的距离/向量的长度
double len()
{
return hypot(x,y);
}
//点到源点距离的平方
double len2()
{
return x*x+y*y;
}
//两点间的距离
double distance(point p)
{
return hypot(x-p.x,y-p.y);
}
//向量加
point add(point p)
{
return point(x+p.x,y+p.y);
}
//向量减
point sub(point p)
{
return point(x-p.x,y-p.y);
}
//向量乘
point mul(double b)
{
return point(x*b,y*b);
}
//向量除
point div(double b)
{
return point(x/b,y/b);
}
//点乘
double dot(point p)
{
return x*p.x+y*p.y;
}
//叉乘
double det(point p)
{
return x*p.y-y*p.x;
}
//XXXXXXX
double rad(point a,point b)
{
point p=*this;
return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
}
//截取长度r
point trunc(double r)
{
double l=len();
if (!dblcmp(l))return *this;
r/=l;
return point(x*r,y*r);
}
//左转90度
point rotleft()
{
return point(-y,x);
}
//右转90度
point rotright()
{
return point(y,-x);
}
//绕点p逆时针旋转angle角度
point rotate(point p,double angle)
{
point v=this->sub(p);
double c=cos(angle),s=sin(angle);
return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
}
};
/*
线段/直线
*/
struct line
{
point a,b;
line(){}
line(point _a,point _b)
{
a=_a;
b=_b;
}
//判断线段相等
bool operator==(line v)
{
return (a==v.a)&&(b==v.b);
}
//点p做倾斜角为angle的射线
line(point p,double angle)
{
a=p;
if (dblcmp(angle-pi/)==)
{
b=a.add(point(,));
}
else
{
b=a.add(point(,tan(angle)));
}
}
//直线一般式ax+by+c=0
line(double _a,double _b,double _c)
{
if (dblcmp(_a)==)
{
a=point(,-_c/_b);
b=point(,-_c/_b);
}
else if (dblcmp(_b)==)
{
a=point(-_c/_a,);
b=point(-_c/_a,);
}
else
{
a=point(,-_c/_b);
b=point(,(-_c-_a)/_b);
}
}
//读入一个线段
void input()
{
a.input();
b.input();
}
//校准线段两点
void adjust()
{
if (b<a)swap(a,b);
}
//线段长度
double length()
{
return a.distance(b);
}
//直线倾斜角 0<=angle<180
double angle()
{
double k=atan2(b.y-a.y,b.x-a.x);
if (dblcmp(k)<)k+=pi;
if (dblcmp(k-pi)==)k-=pi;
return k;
}
//点和线段关系
//1 在逆时针
//2 在顺时针
//3 平行
int relation(point p)
{
int c=dblcmp(p.sub(a).det(b.sub(a)));
if (c<)return ;
if (c>)return ;
return ;
}
//点是否在线段上
bool pointonseg(point p)
{
return dblcmp(p.sub(a).det(b.sub(a)))==&&dblcmp(p.sub(a).dot(p.sub(b)))<=;
}
//两线是否平行
bool parallel(line v)
{
return dblcmp(b.sub(a).det(v.b.sub(v.a)))==;
}
//线段和线段关系
//0 不相交
//1 非规范相交
//2 规范相交
int segcrossseg(line v)
{
int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
if ((d1^d2)==-&&(d3^d4)==-)return ;
return (d1==&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=||
d2==&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=||
d3==&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=||
d4==&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=);
}
//线段和直线v关系
int linecrossseg(line v)//*this seg v line
{
int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
if ((d1^d2)==-)return ;
return (d1==||d2==);
}
//直线和直线关系
//0 平行
//1 重合
//2 相交
int linecrossline(line v)
{
if ((*this).parallel(v))
{
return v.relation(a)==;
}
return ;
}
//求两线交点
point crosspoint(line v)
{
double a1=v.b.sub(v.a).det(a.sub(v.a));
double a2=v.b.sub(v.a).det(b.sub(v.a));
return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
}
//点p到直线的距离
double dispointtoline(point p)
{
return fabs(p.sub(a).det(b.sub(a)))/length();
}
//点p到线段的距离
double dispointtoseg(point p)
{
if (dblcmp(p.sub(b).dot(a.sub(b)))<||dblcmp(p.sub(a).dot(b.sub(a)))<)
{
return min(p.distance(a),p.distance(b));
}
return dispointtoline(p);
}
//XXXXXXXX
point lineprog(point p)
{
return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
}
//点p关于直线的对称点
point symmetrypoint(point p)
{
point q=lineprog(p);
return point(*q.x-p.x,*q.y-p.y);
}
}; /*
多边形
*/
struct polygon
{
int n;//点个数
point p[maxp];//顶点
//读入一个多边形
void input(int n)
{
for (int i=;i<n;i++)
{
p[i].input();
}
}
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=dblcmp(a.sub(p).det(b.sub(p)));
if (d==)
{
return dblcmp(a.distance(p)-b.distance(p))<;
}
return d>;
}
};
void norm()
{
point mi=p[];
for (int i=;i<n;i++)mi=min(mi,p[i]);
sort(p,p+n,cmp(mi));
}
//求凸包存入多边形convex
void getconvex(polygon &convex)
{
int i,j,k;
sort(p,p+n);
convex.n=n;
for (i=;i<min(n,);i++)
{
convex.p[i]=p[i];
}
if (n<=)return;
int &top=convex.n;
top=;
for (i=;i<n;i++)
{
while (top&&convex.p[top].sub(p[i]).det(convex.p[top-].sub(p[i]))<=)
top--;
convex.p[++top]=p[i];
}
int temp=top;
convex.p[++top]=p[n-];
for (i=n-;i>=;i--)
{
while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-].sub(p[i]))<=)
top--;
convex.p[++top]=p[i];
}
}
//取得周长
double getcircumference()
{
double sm=;
int i;
for (i=;i<n;i++)
{
sm+=p[i].distance(p[(i+)%n]);
//printf("%.2f\n",sm);
}
return sm;
}
}; struct polygon P,R;
int N,L;
double sum=; int main()
{
//freopen("in2.txt","r",stdin); cin>>N>>L;
P.n=N;
P.input(N);
P.getconvex(R); sum=R.getcircumference();
//cout<<R.n<<endl;
//for (int i=0;i<R.n;i++)
// printf("%.2f %.2f\n",R.p[i].x,R.p[i].y); sum+=3.14159265358979723846*(double)L*;
printf("%.0f\n",sum); return ;
}

最基础的凸包算法:卷包裹算法。基本思想就好像把所有的点比作一堆钉子,拿一根绳子捆在最左边的点上,然后按顺时针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:如果删掉了还是在右边的话就接着删

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

poj1113 凸包的更多相关文章

  1. poj1113凸包

    就是求凸包的周长加以l为半径的圆周长,证明略 由于之前写过叉积,所以graham扫描算法不是很难理解 #include<map> #include<set> #include& ...

  2. POJ 1113 - Wall 凸包

    此题为凸包问题模板题,题目中所给点均为整点,考虑到数据范围问题求norm()时先转换成double了,把norm()那句改成<vector>压栈即可求得凸包. 初次提交被坑得很惨,在GDB ...

  3. [POJ1113&POJ1696]凸包卷包裹算法和Graham扫描法应用各一例

    凸包的算法比较形象好理解 代码写起来也比较短 所以考前看一遍应该就没什么问题了..>_< POJ1113 刚开始并没有理解为什么要用凸包,心想如果贴着城堡走不是更好吗? 突然发现题目中有要 ...

  4. POJ1113 Wall —— 凸包

    题目链接:https://vjudge.net/problem/POJ-1113 Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submis ...

  5. POJ-1113 Wall 计算几何 求凸包

    题目链接:https://cn.vjudge.net/problem/POJ-1113 题意 给一些点,求一个能够包围所有点且每个点到边界的距离不下于L的周长最小图形的周长 思路 求得凸包的周长,再加 ...

  6. (模板)poj1113(graham扫描法求凸包)

    题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code ...

  7. POJ1113:Wall (凸包算法学习)

    题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...

  8. [poj1113][Wall] (水平序+graham算法 求凸包)

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

  9. 【POJ1113】Wall(凸包)

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

随机推荐

  1. SQL使用开窗函数与CTE查询每月销售额的前几名

    WITH tagTab AS( SELECT YearMonth, pm=RANK() OVER(PARTITION BY YearMonth ORDER BY amount DESC) FROM S ...

  2. Could not load file or assembly 'System.Data.SQLite' or one of its dependencies

    试图加载格式不正确的程 异常类型 异常消息Could not load file or assembly 'System.Data.SQLite' or one of its dependencies ...

  3. DefaultFilesMiddleware中间件如何显示默认页面

    DefaultFilesMiddleware中间件如何显示默认页面 DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认 ...

  4. 数据库 Linux下的MySQL数据库管理

    数据库就是数据的集合. 关系数据库是一种特殊的数据库,他将数据组织城标,并表示为表之间的关系. 数据库系统往往是大型项目的核心数据内容,如银行的用户账户信息,腾讯QQ的用户账户信息.股市的各种交易信息 ...

  5. QT TCP文件上传服务器

    利用QT做为client端,纯C语言做为server端,利用tcp协议,实现client端向server端传递文件 Linux服务器端 //头文件 #include <stdio.h> # ...

  6. opencv1-安装及资料

    本科用过opencv2..3.1版本,当时按照 http://wiki.opencv.org.cn/index.php/首页 上面的步骤安装的,而且使用的是IplImage和CvMat等C接口的的AP ...

  7. <实训|第六天>偷偷让新手的Linux无限重启附linux主机名称不是随便乱改的!

    先说个事情:这几天我正在忙一个项目的设计,8月1号之前要弄出来,所以每天都要弄到很晚,可能更新就有点跟不上了,不过我如果有时间的话,我就更新,没时间的话,我会在8月1号之后统一更新出来,希望大家谅解! ...

  8. vNext之旅(1):从概念和基础开始

    ASP.NET vNext or .NET vNext? vNext在曝光以来绝大多数以ASP.NET vNext这样的的字眼出现,为什么这边会提及.NET vNext?原因是我认为ASP.NET只是 ...

  9. C#,JavaScript两种语言 2048小游戏

    <html> <head> <style type="text/css"> .haha { border-width: 2; font-size ...

  10. js中return的用法

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...