poj1113 凸包
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 凸包的更多相关文章
- poj1113凸包
就是求凸包的周长加以l为半径的圆周长,证明略 由于之前写过叉积,所以graham扫描算法不是很难理解 #include<map> #include<set> #include& ...
- POJ 1113 - Wall 凸包
此题为凸包问题模板题,题目中所给点均为整点,考虑到数据范围问题求norm()时先转换成double了,把norm()那句改成<vector>压栈即可求得凸包. 初次提交被坑得很惨,在GDB ...
- [POJ1113&POJ1696]凸包卷包裹算法和Graham扫描法应用各一例
凸包的算法比较形象好理解 代码写起来也比较短 所以考前看一遍应该就没什么问题了..>_< POJ1113 刚开始并没有理解为什么要用凸包,心想如果贴着城堡走不是更好吗? 突然发现题目中有要 ...
- POJ1113 Wall —— 凸包
题目链接:https://vjudge.net/problem/POJ-1113 Wall Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- POJ-1113 Wall 计算几何 求凸包
题目链接:https://cn.vjudge.net/problem/POJ-1113 题意 给一些点,求一个能够包围所有点且每个点到边界的距离不下于L的周长最小图形的周长 思路 求得凸包的周长,再加 ...
- (模板)poj1113(graham扫描法求凸包)
题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code ...
- POJ1113:Wall (凸包算法学习)
题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...
- [poj1113][Wall] (水平序+graham算法 求凸包)
Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...
- 【POJ1113】Wall(凸包)
[题目] Description Once upon a time there was a greedy King who ordered his chief Architect to build a ...
随机推荐
- mysql查看数据库和表的占用空间大小
mysql查看数据库和表的占用空间大小 第一部分-任务 将线上db,导出后,导入到office db 一. 两种方案: 1,将数据直接从online-->office,通过mysqldump ...
- noi1696 逆波兰表达式
1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...
- Node基础:url查询参数解析之querystring
模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). .stringify() ...
- C#操作Excel时的格式设定(转)
Excel报表打印的格式设定 1. 表头的设置 Excel._Worksheet myWorksheet; myWorksheet.PageSetup.Orientation = Excel. ...
- j-link或者swd调试
两种 一.JTAG调试(5针), 二.SWD调试(2针), 在JTAG/SWD模式设置库函数 (在文件stm32f10x_gpio.c中): void GPIO_PinRemapConfig(uint ...
- background-size对background-position的影响
CSS3中提出了background-size属性,该属性可以设置背景图片的大小,该属性的值设置为绝对数值或者百分比时对background-position没有任何影响,当设置为contain/co ...
- .net MVC全球化资源使用心得
网上有的我就不说了,我只记录下我碰壁的事情. local资源就不说,这里只说global全局资源文件. 假设新建一个资源文件名称叫做resourceA, 下面几点记录备忘: resouceA就是Get ...
- Chrome 自动填充的表单是淡黄色的背景
Chrome 自动填充的表单是淡黄色的背景解决方案; input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px #fff inset; - ...
- iOS开发-- 利用AVPlayer播放远程音乐和视频
一.简单的播放音乐和视频,播放视频的工具栏需要自己写 二.利用老师封装的框架实现视频播放 链接:http://pan.baidu.com/s/1hrEKlus 密码:8e7g
- 【BZOJ 2038】【2009 国家集训队】小Z的袜子(hose) 分块+莫队
$SDOI2016Day-1$临时抱佛脚学习一下莫队算法$233$ 我预感到自己省选要爆0hhh #include<cmath> #include<cstdio> #inclu ...