【模板大法好】 凸包模板(以及poj1113题代码)
2016-06-08 22:27
495 查看
首先根据极角排序(为什么叫极角?),其实就是选左下角的点,然后根据其他点与这个点所成直线与水平方向的夹角从小到大排序。。。具体的话要用到向量叉积这个东西,据某教说这是高一就学的数学知识,然而我并不知道?具体就是若有向量a(x1,y1),与向量b(x2,y2),如果x1*y2-x2*y1>0那么向量a向左转后与向量b重合,然后根据这个式子维护一个栈来存凸包上的点,如果 栈最后的两个点构成的向量 右转后与 栈尾和新点所构成的向量重合,那么栈尾的这个点就可以滚粗了,大概就是这样,原理的话懒得解释了,找别人的博客去看吧。。。orz
代码:
模板题推荐:poj1113 注意精度上的四舍五入(^.^)
poj1113题的代码:
代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<math.h> using namespace std; struct node { int x;int y; }p[1005],s[1005]; int n,m; int sq(int x) { return x*x; } int chaji(node a1,node a2,node b1,node b2) { //叉积大于0,则a左转后到b return (a2.x-a1.x)*(b2.y-b1.y)-(b2.x-b1.x)*(a2.y-a1.y); } double dis(node p1,node p2) { return sqrt( (double)sq(p2.y-p1.y)*1.0+(double)sq(p2.x-p1.x)*1.0 ); } bool cmp1(node p1,node p2) { if (p1.x!=p2.x) return p1.x<p2.x; return p1.y<p2.y; } bool cmp2(node p1,node p2) { int tmp=chaji(p[1],p1,p[1],p2); if (tmp>0) return 1; if (tmp==0 && dis(p[0],p1)<dis(p[0],p2)) return 1; return 0; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); sort(p+1,p+1+n,cmp1); sort(p+2,p+1+n,cmp2); s[1]=p[1]; int tot=1; for (int i=2;i<=n;i++) { while(tot>1 && chaji(s[tot-1],s[tot],s[tot],p[i])<=0) tot--; tot++; s[tot]=p[i]; } for (int i=1;i<=tot;i++) printf("%d %d\n",s[i].x,s[i].y); return 0; }
模板题推荐:poj1113 注意精度上的四舍五入(^.^)
poj1113题的代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<math.h> using namespace std; struct node { int x;int y; }p[1005],s[1005]; int n,m; int sq(int x) { return x*x; } int chaji(node a1,node a2,node b1,node b2) { //叉积大于0,则a左转后到b return (a2.x-a1.x)*(b2.y-b1.y)-(b2.x-b1.x)*(a2.y-a1.y); } double dis(node p1,node p2) { return sqrt( (double)sq(p2.y-p1.y)*1.0+(double)sq(p2.x-p1.x)*1.0 ); } bool cmp1(node p1,node p2) { if (p1.x!=p2.x) return p1.x<p2.x; return p1.y<p2.y; } bool cmp2(node p1,node p2) { int tmp=chaji(p[1],p1,p[1],p2); if (tmp>0) return 1; if (tmp==0 && dis(p[0],p1)<dis(p[0],p2)) return 1; return 0; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); sort(p+1,p+1+n,cmp1); sort(p+2,p+1+n,cmp2); s[1]=p[1]; int tot=1; for (int i=2;i<=n;i++) { while(tot>1 && chaji(s[tot-1],s[tot],s[tot],p[i])<=0) tot--; tot++; s[tot]=p[i]; } double ans=0.0; s[tot+1]=s[1]; for (int i=1;i<=tot;i++) ans+=dis(s[i],s[i+1]); double tmp=2.0*acos(-1.0)*(double)m; ans+=tmp; int zans=(int)(ans+0.5); printf("%d\n",zans); } return 0; }
相关文章推荐
- 设计模式之行为型模式 - 调用行为的传递问题
- [div+css]晒晒最新制作专题推广页模板
- 2008大学生入党申请书 模板
- IMAIL多语言模板两套Outlook&Gmail模板下载
- 在PHP中使用模板的方法
- 深入解析php模板技术原理【一】
- Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
- 在ASP中不用模板生成HTML静态页直接生成.html页面
- 基于HTML模板和JSON数据的JavaScript交互(移动端)
- C#模板方法模式(Template Method Pattern)实例教程
- javascript文本模板用法实例
- 关于Asp代码与页面的分离模板技术第1/3页
- php模板原理讲解
- 需要使用php模板的朋友必看的很多个顶级PHP模板引擎比较分析
- DataGrid 动态添加模板列 实现代码
- 详解java模板和回调机制
- C++模板之特化与偏特化详解
- vs.net2008添加模板方法
- ThinkPHP模板判断输出Empty标签用法详解
- ThinkPHP模板范围判断输出In标签与Range标签用法详解