计算几何之凸包
来源:互联网 发布:网络情缘陈星 编辑:程序博客网 时间:2024/05/13 10:43
这个内容我看了半天,我还是不大清楚,主要靠模板了,更多的知识点击这里,下面是凸包的构造过程:
凸包模板为(我把结构体也写了出来):
struct Point { double x,y; friend istream& operator>>(istream &cin,Point &p) { cin>>p.x>>p.y; } friend ostream& operator<<(ostream &cout,Point &p) { cout<<p.x<<" "<<p.y; return cout; } bool operator<(const Point& p) const { return y<p.y||(y==p.y&&x<p.x); } };bool multi(Point p1,Point p2,Point p){ return (p1.x-p.x)*(p2.y-p.y)>(p2.x-p.x)*(p1.y-p.y);}Point P[MAX],res[MAX]; //res保存凸包中的顶点 int Graph(){ int top=1; //返回凸包中点的个数 sort(P,P+n); if(n==0) return 0; res[0]=P[0]; if(n==1) return 1; res[1]=P[1]; if(n==2) return 2; res[2]=P[2]; for(int i=2;i<n;i++) { while(top && multi(P[i],res[top],res[top-1])) top--; res[++top]=P[i]; } int len=top; res[++top]=P[n-2]; for(int i=n-3;i>=0;i--) { while(top!=len && multi(P[i],res[top],res[top-1])) top--; res[++top]=P[i]; } return top;}
凸包的题目用这个模板一般可以过,但是一般不会单纯的考凸包,会结合旋转卡壳的知识来出题,这里包涵了大多数旋转卡壳的知识。
题1:Tyvj 1150(绳子围点),先用凸包求出最大面积,然后利用Pick定理求出点即可。注意精度问题,统一用__int64型的就行。
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;const int MAX=200010;struct Point{ __int64 x,y; bool operator<(const Point &P) const { return y<P.y||(y==P.y&&x<P.x); } };Point P[MAX],res[MAX];__int64 Gcd(__int64 n,__int64 m){ return m==0?n:Gcd(m,n%m);}__int64 multi(Point P0,Point P1,Point P2){ return (P1.x-P0.x)*(P2.y-P0.y)>(P2.x-P0.x)*(P1.y-P0.y);} __int64 Graph(__int64 n) { __int64 top=1; sort(P,P+n); if(n==0) return 0; res[0]=P[0]; if(n==1) return 1; res[1]=P[1]; if(n==2) return 2; res[2]=P[2]; for(int i=2;i<n;i++) { while(top && multi(P[i],res[top],res[top-1])) top--; res[++top]=P[i]; } __int64 len=top; res[++top]=P[n-2]; for(int i=n-3;i>=0;i--) { while(top!=len && multi(P[i],res[top],res[top-1])) top--; res[++top]=P[i]; } return top; } __int64 Area(__int64 n) { __int64 area=0; for(int i=1;i<=n;i++) area+=res[i-1].x*res[i%n].y-res[i%n].x*res[i-1].y; return area>0?area:-area; } __int64 Count(__int64 n) { __int64 sum=0; for(int i=1;i<=n;i++) { int dx=abs(res[i%n].x-res[i-1].x); int dy=abs(res[i%n].y-res[i-1].y); sum+=Gcd(dx,dy); } return sum; } int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%I64d%I64d",&P[i].x,&P[i].y); __int64 len=Graph(n); __int64 I=(Area(len)-Count(len))/2+1; printf("%I64d\n",I+Count(len)); return 0;}
- 计算几何之凸包
- 计算几何学习笔记之凸包
- 计算几何之凸包模板
- 计算几何-凸包
- [计算几何]凸包算法
- 计算几何-凸包问题
- 计算几何 --- 凸包 模板
- 计算几何凸包详解
- 计算几何之凸包_卷包裹算法
- 计算几何之凸包----Graham扫描法
- 计算几何之凸包(三) {旋转卡壳初步}
- 计算几何之二维三维凸包算法
- 算法学习笔记之计算几何--平面凸包
- 计算几何中的凸包计算
- 计算几何__凸包算法
- [计算几何]凸包算法 收藏
- [计算几何-凸包]pku1113-Wall
- 计算几何 Graham_scan凸包 pku 1113
- SourceInsight explorer自定义命令
- DedeCMS---本地安装时进入后台密码的修改
- 蓝点杯 打印整数划分问题
- javascript:浮动div,可拖拽div,遮罩层(div和iframe实现)
- POCO NotificationQueue Sample疑问
- 计算几何之凸包
- Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用
- C 语言Shell 排序
- 短信发送--短信发送流程--应用层
- 数据库笔记六——存储过程
- ipv6地址解读---子网掩码
- Android中获取应用程序(包)的信息-----PackageManager的使用(一)
- 【解决方案】ItemsControl删除元素,但仍然显示它们
- linux内核中符号地址的获取