博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【HDOJ】1348 Wall【计算几何-凸包】
阅读量:6271 次
发布时间:2019-06-22

本文共 3461 字,大约阅读时间需要 11 分钟。

临近区域赛,想要系统地过一下知识点,发现了一个好网站,推荐一波。

(杭电牛逼)

第一次做凸包题

题意就是求凸包构成的多边形周长+一个圆的周长

凸包的概念

在二维欧几里得空间中,凸包可想象为一条刚好包着所有点的橡皮圈。

1484685-20181010162827509-1804343018.png

求凸包的方法

《算导》给了两种方法

  1. Graham扫描法
  2. Jarvis步近法
    详见《算导》

我这边用的是《算法竞赛入门经典-训练指南》里的模板,基于水平序的Andrew算法(是 Graham扫描法的变种,更快且数值稳定性更好)。

int ConvexHull(Point *p,int n,Point *ch){    sort(p,p+n);//先比较x坐标,再比较y坐标    int m=0;    for(int i=0;i
1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } int k=m; for(int i=n-2;i>=0;i--) { while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } if(n>1) m--; return m;}

实在是太菜了,感觉对的啊,又没能AC

My Wrong Code And Online AC Code

/*核心:求凸包*/#include
#define rep(i,a,b) for(int i=a;i<=b;i++)using namespace std;const int maxn=1005;struct Point{ double x,y; //构造函数 Point(double x=0,double y=0 ):x(x),y(y){}};typedef Point Vector;// 别名const double eps=1e-10;Vector operator + (Vector A,Vector B){ return Vector(A.x+B.x,A.y+B.y);}Vector operator - (Point A,Point B){ return Vector(A.x-B.x,A.y-B.y);}Vector operator * (Point A,double p){ return Vector(A.x*p,A.y*p);}Vector operator / (Point A,double p){ return Vector(A.x/p,A.y/p);}bool operator <(const Point&a,const Point &b){ return a.x
1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } int k=m; for(int i=n-2;i>=0;i--) { while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } if(n>1) m--; return m;}double distance (Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}Point p[maxn],ch[maxn];int main(){ int t; scanf("%d",&t); while(t--) { int n,l; scanf("%d%d",&n,&l); for(int i=0;i
#include
#include
#include
using namespace std; const int MAXN = 1005;const double PI = acos(-1.0);const double EPS = 1E-6; int T, N, L; struct Point{ int x; int y;} p[MAXN];vector
vec; double dist(Point a, Point b) { return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));} double crossProduct(Point a, Point b, Point c) { // ab * ac return (b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x) - 0.0;} bool cmp(Point a, Point b) { double cp = crossProduct(p[0], a, b); if (cp > EPS) return true; else if (cp < -EPS) return false; else return dist(p[0], a) < dist(p[0], b);} int findLf(Point p[]) { // find lowest leftest point/vertice. int index = 0; for (int i = 1; i < N; i++) { if (p[i].y < p[index].y) index = i; else if (p[i].y == p[index].y && p[i].x < p[index].x) index = i; } return index;} void graham(Point p[]) { // graham algorithm for convex hall. vec.clear(); vec.push_back(p[0]); vec.push_back(p[1]); int top = 1; for (int i = 2; i < N; i++) { // another way: i <= N, and comment the line below:ans += dist(vec[vec.size() - 1], vec[0]); while (top >= 1 && crossProduct(vec[top - 1], vec[top], p[i]) <= 0) { vec.pop_back(); top--; } vec.push_back(p[i]); top++; }} int main() { cin >> T; while (T--) { cin >> N >> L; for (int i = 0; i < N; ++i) { cin >> p[i].x >> p[i].y; } int lf = findLf(p); swap(p[0], p[lf]); p[N] = p[0]; sort(p + 1, p + N, cmp); graham(p); double ans = 0.0; for (int i = 1; i < (int)vec.size(); i++) { ans += dist(vec[i - 1], vec[i]); } ans += dist(vec[vec.size() - 1], vec[0]); ans += 2 * PI * L; cout << (int)round(ans) << endl; if (T) cout << endl; } return 0;}*/

转载于:https://www.cnblogs.com/shengwang/p/9767374.html

你可能感兴趣的文章
欧几里德算法与扩展欧几里德算法
查看>>
Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 2)
查看>>
通过kafka提供的命令来查看offset消费情况
查看>>
oracle数据库从入门到精通之四
查看>>
自定义圆形图片控件
查看>>
sharepoint 2013 补丁升级步骤
查看>>
asp.net core 2.0 web api基于JWT自定义策略授权
查看>>
Skype for Business Server 2015-04-前端服务器-3-安装-管理工具
查看>>
第12章代码《跟老男孩学习Linux运维:Shell编程实战》
查看>>
我们为什么从Python转到go?
查看>>
5.Azure负载均衡(上)
查看>>
轻松精通awk数组企业问题案例
查看>>
26.Azure备份服务器(下)
查看>>
从“网上说的能信么”说开去---学习的思考
查看>>
DHCP 日志分析
查看>>
.NET Micro Framework动态调用C/C++底层代码(原理篇)
查看>>
Windows Server 2012正式版RDS系列⒃
查看>>
Shell脚本之awk篇
查看>>
微软发布Azure Stack硬件需求
查看>>
python socket编程详细介绍
查看>>