计蒜客47——圈果树(二维凸包)
来源:互联网 发布:淘宝客服9月月度总结 编辑:程序博客网 时间:2024/04/28 07:06
传送门
小马承包了一个果园,想修一个围栏,但是不希望砍掉任何的果树。对于给出的所有的果树的坐标,计算一下最小的围住所有的果树的围栏的长度。
输入数据的第一行包括一个整数 N(0≤ N ≤10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个由空格分隔的实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 ≤ Xi,Yi ≤ 1,000,000)。数字用小数表示。
输出包括一个实数,表示必须的围栏的长度(保留两位有效小数)
样例输入
4
4 8
4 12
5 9.3
7 8
样例输出
12.00解题思路:
直接计算一个二维凸包,然后计算凸包上相邻两两点的距离,然后加和就是周长。
代码:
#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const double INF = 1e18+5;const int MAXN = 1e4 + 5;const double eps = 1e-10;const double PI = acos(-1.0);int double_cmp(double x){ if(fabs(x) < eps) return 0; if(x > 0) return 1; return -1;}struct Point{ double x, y; int id; Point() {} Point (double _x, double _y, int i):x(_x),y(_y),id(i) {} bool operator <(const struct Point &tmp)const { if(double_cmp(x-tmp.x) == 0) return double_cmp(y-tmp.y) < 0; return double_cmp(x-tmp.x) < 0; } bool operator == (const struct Point &tmp)const { return double_cmp(x-tmp.x)==0&&double_cmp(y-tmp.y)==0; }} p[MAXN],st[MAXN];bool cmp(const Point& p1, const Point& p2){ return atan2(p1.y, p1.x) < atan2(p2.y, p2.x);}double XMulti(Point a, Point b, Point c)///ac X ab{ return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);}double dis(Point a, Point b){ return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}double dis2(Point a, Point b){ return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);}double dot(Point a, Point b, Point c)///点积 ab . ac{ double s1 = b.x-a.x; double t1 = b.y-a.y; double s2 = c.x-a.x; double t2 = c.y-a.y; return s1*s2 + t1*t2;}int ConvexHull(Point *p, int n, Point *st)///凸包{ sort(p, p+n); n = unique(p, p+n)-p;///去重 int m = 0; for(int i=0; i<n; i++) { while(m>1 && XMulti(st[m-2],p[i],st[m-1])<=0) m--; st[m++] = p[i]; } int k = m; for(int i=n-2; i>=0; i--) { while(m>k && XMulti(st[m-2],p[i],st[m-1])<=0) m--; st[m++] = p[i]; } if(n > 1) m--; return m;}int main(){ int n; while(~scanf("%d",&n)){ for(int i=0; i<n; i++) scanf("%lf%lf",&p[i].x, &p[i].y); int cnt = ConvexHull(p, n, st); double sum = dis(st[0],st[cnt-1]); for(int i=0; i<cnt-1; i++) sum += dis(st[i], st[i+1]); printf("%.2f\n",sum); } return 0;}
阅读全文
0 0
- 计蒜客47——圈果树(二维凸包)
- nyoj 圈水池 78 (二维凸包 数学几何) 凸包入门
- 凸包问题——圈水池
- 圈水池(凸包)
- 凸包问题——圈水池(nyist 78)
- 计算几何凸包——NYOJ78圈水池
- NYOJ 圈水池(凸包问题)
- 凸包问题(圈水池)
- NYIST78-圈水池(凸包)
- [nyoj78]圈水池(凸包入门)
- NYOJ78 圈水池(凸包模板)
- nyoj78圈水池(凸包问题)
- 计算几何:凸包(圈水池)
- [COGS896]圈奶牛(凸包)
- [cogs 896]圈奶牛(凸包)
- COGS 896. 圈奶牛 (凸包)
- cogs896 圈奶牛(凸包)
- 果树
- JVM(8):JVM知识点总览-高级Java工程师面试必备
- json语法
- jackson的一个并发死锁的问题
- GO http的一些初级小例子
- 40_面向对象_13_继承_Object类用法_toString和equals方法_重写toString
- 计蒜客47——圈果树(二维凸包)
- 【网络与通信】网络基础
- oj 2755: C++习题-希尔排序
- iOS中UIControl的介绍
- Autoencoder review
- Linux和Windows平台下文件路径的异同
- BZOJ4868: [Shoi2017]期末考试
- USACO-Section 1.4 Arithmetic Progressions
- dsfasd