POJ 3608 Bridge Across Islands(模板小汇)
来源:互联网 发布:端口查询 编辑:程序博客网 时间:2024/06/05 12:34
求两个凸包间的最短距离。
大部分都是抄的小岛前辈的模板。
真是无私奉献的典范啊!应有尽有,巨细靡遗。。
顺便连带整理了一下自己的。(感觉自己的模板也写得变紧凑了。。)
#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>#include <stdio.h>#include <math.h>using namespace std;#define MAXN 10010#define eps 1e-10//const double pi = acos(-1.0);inline double sig(double x) { return (x > eps) - (x < -eps); };template <class T> inline T sqr(T a) { return a * a; }struct Point{ double x, y; Point() {} Point(double _x, double _y): x(_x), y(_y) {} void in(); void out() const; double len() const; double len2() const; double dis(const Point &argu) const; double dis2(const Point &argu) const; bool operator <(const Point &argu) const; Point operator -(const Point &argu) const; double operator ^(const Point &argu) const; double operator *(const Point &argu) const;};struct Segment{ Point a, b; Segment() {} Segment(Point _a, Point _b): a(_a), b(_b) {} void in(); Point d() const; void out() const; double len() const; double len2() const; int sgn(const Segment &argu) const; bool qrt(const Segment &argu) const; double dis2(const Point &argu) const; double dis2(const Segment &argu) const;};struct Line{ Segment l; Line() {} Line(Segment _l): l(_l) {} double dis2(const Point &argu) const; double dis2(const Segment &argu) const;};inline double Cross(const Point &o, const Point &a, const Point &b) { return (a - o) ^ (b - o); }void Point::in() { scanf("%lf%lf", &x, &y); }double Point::len() const { return sqrt(len2()); }double Point::len2() const { return x * x + y * y; }void Point::out() const{ printf("%.0lf %.0lf\n", x, y); }double Point::dis(const Point &argu) const { return sqrt(dis2(argu)); }double Point::operator ^(const Point &argu) const { return x * argu.y - y * argu.x; }double Point::operator *(const Point &argu) const { return x * argu.x + y * argu.y; }Point Point::operator -(const Point &argu) const { return Point(x - argu.x, y - argu.y); }bool Point::operator <(const Point &argu) const { return sig(x - argu.x) == 0 ? y < argu.y : x < argu.x; }double Point::dis2(const Point &argu) const { return (x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y); }void Segment::in() { a.in(), b.in(); }Point Segment::d() const { return b - a; }double Segment::len2() const { return d().len2(); }double Segment::len() const { return sqrt(len2()); }void Segment::out() const { a.out(), b.out(); }double Segment::dis2(const Segment &argu) const{ if(~sgn(argu)) return 0; return min(min(dis2(argu.a), dis2(argu.b)), min(argu.dis2(a), argu.dis2(b)));}double Segment::dis2(const Point &argu) const{ Point pa = argu - a, pb = argu - b; if(sig(d() * pa) <= 0) return pa.len2(); if(sig(d() * pb) >= 0) return pb.len2(); Line l = Line((*this)); return l.dis2(argu);}int Segment::sgn(const Segment &argu) const{ if(!qrt(argu)) return -1; return sig(Cross(a, b, argu.a)) * sig(Cross(a, b, argu.b)) <= 0 && sig(Cross(argu.a, argu.b, a)) * sig(Cross(argu.a, argu.b, b)) <= 0 ? 1 : -1;}//快速排斥实验bool Segment::qrt(const Segment &argu) const{ return min(a.x, b.x) <= max(argu.a.x, argu.b.x) && min(a.y, b.y) <= max(argu.a.y, argu.b.y) && min(argu.a.x, argu.b.x) <= max(a.x, b.x) && min(argu.a.y, argu.b.y) <= max(a.y, b.y);}double Line::dis2(const Point &argu) const { return sqr(fabs(l.d() ^ (argu - l.a))) / l.len2(); }double Line::dis2(const Segment &argu) const{ Point v1 = argu.a - l.a, v2 = argu.b - l.b; double d1 = l.d() ^ v1, d2 = l.d() ^ v2; return sig(d1) != sig(d2) ? 0 : sqr(min(fabs(d1), fabs(d2))) / l.len2();}int ConvexHull(Point p[], Point ch[], int n){ sort(p, p + n); int top = 0; for(int i = 0; i < n; i++) { while(top > 1 && Cross(ch[top - 2], ch[top - 1], p[i]) <= 0) top--; ch[top++] = p[i]; } int t = top; for(int i = n - 2; i >= 0; i--) { while(top > t && Cross(ch[top - 2], ch[top - 1], p[i]) <= 0) top--; ch[top++] = p[i]; } top--; return top;}double RotatingCalipers(Point p1[], int n1, Point p2[], int n2){ double ret = 1e15; int t = 0, t1 = 1, t2 = 1; for(int i = 0; i < n1; i++) if(p1[i].y > p1[t1].y) t1 = i; for(int i = 0; i < n2; i++) if(p2[i].y < p2[t1].y) t1 = i; for(int i = 0; i < n1; i++) { while(sig((p1[t1 + 1] - p1[t1]) ^ (p2[t2 + 1] - p2[t2])) > 0) t2 = (t2 + 1) % n2; Segment s1 = Segment(p1[t1], p1[t1 + 1]); Segment s2 = Segment(p2[t2], p2[t2 + 1]); ret = min(ret, s1.dis2(s2)); t1 = (t1 + 1) % n1; } return ret;}Point p1[MAXN], ch1[MAXN];Point p2[MAXN], ch2[MAXN];int n1, n2, c1, c2;void solve(){ c1 = ConvexHull(p1, ch1, n1); ch1[c1] = ch1[0]; c2 = ConvexHull(p2, ch2, n2); ch2[c2] = ch2[0]; double d1 = RotatingCalipers(ch1, c1, ch2, c2); double d2 = RotatingCalipers(ch2, c2, ch1, c1); printf("%.5lf\n", sqrt(min(d1, d2)));}int main(){// freopen("3608.in", "r", stdin); while(scanf("%d%d", &n1, &n2) && (n1 || n2)) { for(int i = 0; i < n1; i++) p1[i].in(); for(int i = 0; i < n2; i++) p2[i].in(); solve(); } return 0;}
0 0
- POJ 3608 Bridge Across Islands(模板小汇)
- poj 3608 Bridge Across Islands
- 【POJ 3608】Bridge Across Islands
- POJ 3608 Bridge Across Islands
- POJ 3608 Bridge Across Islands
- Bridge Across Islands POJ
- poj 3608 Bridge Across Islands(旋转卡壳)
- POJ 3608 Bridge Across Islands (计算几何+三分)
- poj 3608 Bridge Across Islands(旋转卡壳求凸包最短距离)
- poj 3608 Bridge Across Islands (计算几何)
- poj 3608 Bridge Across Islands 凸包最短距离
- POJ 3608 Bridge Across Islands(旋转卡壳)
- POJ 3608 Bridge Across Islands 已翻译
- POJ:3608 Bridge Across Islands 旋转卡壳
- poj 3608 Bridge Across Islands(两凸包最近距离)
- POJ 3608 Bridge Across Islands (凸包+旋转卡壳)
- poj 3608 Bridge Across Islands(旋转卡壳求俩凸包间最小间距)
- poj 3608 Bridge Across Islands(两个凸包的最短距离)
- java 解惑3 string 字符串
- java读取配置文件
- 从今天起,写一本关于LLVM的书----《深入理解LLVM》
- 3.Longest Substring Without Repeating Characters
- HMC5883L 电子指南针用树莓派进行磁场干扰过滤 校准
- POJ 3608 Bridge Across Islands(模板小汇)
- STL count_if() with lambda expression
- 1014. Waiting in Line (30)
- 深入C#中get与set的详解
- C# delegate event
- iOS系统网络抓包方法
- style、currentStyle、getComputedStyle区别介绍
- tomcat配置映射虚拟目录
- 你好,自己