zoukankan      html  css  js  c++  java
  • Bridge Across Islands POJ

    (color{#0066ff}{题目描述})

    几千年前,有一个小王国位于太平洋的中部。王国的领土由两个分离的岛屿组成。由于洋流的冲击,两个岛屿的形状都变成了凸多边形。王国的国王想建立一座桥来连接这两个岛屿。为了把成本降到最低,国王要求你,主教,找到两个岛屿边界之间最小的距离。

    (color{#0066ff}{输入格式})

    输入由几个测试用例组成。
    每个测试用两个整数n,m(3≤n,m≤10000)开始
    接下来的n行中的每一行都包含一对坐标,用来描述顶点在一个凸多边形中的位置。
    下一条m线中的每一条都包含一对坐标,它描述了一个顶点在另一个凸多边形中的位置。
    n=m=0的行表示输入的结束。
    坐标在这个范围内[-10000,10000]。

    (color{#0066ff}{输出格式})

    对每个测试用例输出最小距离。在0.001范围内的错误是可以接受的

    (color{#0066ff}{输入样例})

    4 4
    0.00000 0.00000
    0.00000 1.00000
    1.00000 1.00000
    1.00000 0.00000
    2.00000 0.00000
    2.00000 1.00000
    3.00000 1.00000
    3.00000 0.00000
    0 0
    

    (color{#0066ff}{输出样例})

    1.00000
    

    (color{#0066ff}{数据范围与提示})

    none

    (color{#0066ff}{题解})

    旋转卡壳

    输入的时候就是凸包,所以不用再求了

    对于最近距离,可能是点点,点边, 边边,这个可以在点到边的距离那里一并处理

    距离可以通过面积判断(底固定,高最大)

    (叉积是负的,所以用<) 找到高最小的更新ans

    #include <cstdio>
    #include <cmath>
    #include <cctype>
    #include <algorithm>
    #define _ 0
    #define LL long long
    inline LL in() {
    	LL x = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
    	return x * f;
    }
    const int maxn = 1e4 + 100;
    int n, m;
    struct node {
    	double x, y;
    	node(double x = 0, double y = 0)
    		:x(x), y(y) {}
    	node operator - (const node &b) const {
    		return node(x - b.x, y - b.y);
    	}
    	double operator ^ (const node &b) const {
    		return x * b.y - y * b.x;
    	}
    	double operator * (const node &b) const {
    		return x * b.x + y * b.y;
    	}
    	double dis() {
    		return sqrt(x * x + y * y);
    	}
    	double dis(const node &a, const node &b) {
    		node c = *this;
            //垂足不在线段ab上
    		if((b - a) * (c - a) < 0) return (c - a).dis();
    		if((a - b) * (c - b) < 0) return (c - b).dis();
            //平行四边形面积 / 底 = 高
    		return fabs(((a - b) ^ (c - b)) / (a - b).dis());
    	}
    }A[maxn], B[maxn];
    double Min(node a, node b, node c, node d) { 
    	return std::min(std::min(c.dis(a,b),d.dis(a,b)),std::min(a.dis(c,d),b.dis(c,d)));
    }
    double work() {
    	double ans = 1e20;
    	int min = 0, max = 0;
    	for(int i = 0; i < n; i++) if(A[i].y < A[min].y) min = i;
    	for(int i = 0; i < m; i++) if(B[i].y > B[max].y) max = i;
    	A[n] = A[0], B[m] = B[0];
    	for(int i = 0; i < n; i++) {
    		node t = A[min + 1] - A[min];
    		while((t ^ (B[max] - A[min]))  < (t ^ (B[max + 1] - A[min]))) max = (max + 1) % m;
    		ans = std::min(ans, Min(A[min], A[min + 1], B[max], B[max + 1]));
    		min = (min + 1) % n;
    	}
    	return ans;
    }
    int main() {
    	while("fuck") {
    		n = in(), m = in();
    		if(!n && !m) break; 
    		for(int i = 0; i < n; i++) scanf("%lf%lf", &A[i].x, &A[i].y);
    		for(int i = 0; i < m; i++) scanf("%lf%lf", &B[i].x, &B[i].y);
    		printf("%.3f
    ", work());
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java的String类
    Java基本数据类型
    Java历史简介
    Java常量,变量,作用域!强转类型
    JAVA特性与JDK,JRE,JVM!
    JAVA历史简介
    JAVA多线程
    开博了
    quartz学习笔记(一)简单入门
    CentOS-64位安装mysql5.7
  • 原文地址:https://www.cnblogs.com/olinr/p/10193805.html
Copyright © 2011-2022 走看看