zoukankan      html  css  js  c++  java
  • POJ3525 Most Distant Point from the Sea(半平面交)

    给你一个凸多边形,问在里面距离凸边形最远的点。

    方法就是二分这个距离,然后将对应的半平面沿着法向平移这个距离,然后判断是否交集为空,为空说明这个距离太大了,否则太小了,二分即可。

    #pragma warning(disable:4996)
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    #define maxn 2500
    #define eps 1e-7
    
    int n;
    
    int dcmp(double x){
    	return (x > eps) - (x < -eps);
    }
    
    struct Point
    {
    	double x, y;
    	Point(){}
    	Point(double _x, double _y) :x(_x), y(_y){}
    	Point operator + (const Point &b) const{
    		return Point(x + b.x, y + b.y);
    	}
    	Point operator - (const Point &b) const{
    		return Point(x - b.x, y - b.y);
    	}
    	Point operator *(double d) const{
    		return Point(x*d, y*d);
    	}
    	Point operator /(double d) const{
    		return Point(x / d, y / d);
    	}
    	double det(const Point &b) const{
    		return x*b.y - y*b.x;
    	}
    	double dot(const Point &b) const{
    		return x*b.x + y*b.y;
    	}
    	Point rot90(){
    		return Point(-y, x);
    	}
    	Point norm(){
    		double len=sqrt(this->dot(*this));
    		return Point(x, y) / len;
    	}
    	void read(){
    		scanf("%lf%lf", &x, &y);
    	}
    };
    
    #define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
    #define crossOp(p1,p2,p3) (dcmp(cross(p1,p2,p3)))
    
    Point isSS(Point p1, Point p2, Point q1, Point q2){
    	double a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2);
    	return (p1*a2 + p2*a1) / (a1 + a2);
    }
    
    struct Border
    {
    	Point p1, p2;
    	double alpha;
    	void setAlpha(){
    		alpha = atan2(p2.y - p1.y, p2.x - p1.x);
    	}
    };
    
    bool operator < (const Border &a,const Border &b) {
    	int c = dcmp(a.alpha - b.alpha);
    	if (c != 0) {
    		return c == 1;
    	}
    	else {
    		return crossOp(b.p1, b.p2, a.p1) > 0;
    	}
    }
    
    bool operator == (const Border &a, const Border &b){
    	return dcmp(a.alpha - b.alpha) == 0;
    }
    
    
    Point isBorder(const Border &a, const Border &b){
    	return isSS(a.p1, a.p2, b.p1, b.p2);
    }
    
    Border border[maxn];
    Border que[maxn];
    int qh, qt;
    // check函数判断的是新加的半平面和由a,b两个半平面产生的交点的方向,若在半平面的左侧返回True
    bool check(const Border &a, const Border &b, const Border &me){
    	Point is = isBorder(a, b);
    	return crossOp(me.p1, me.p2, is) > 0;
    }
    
    bool convexIntersection()
    {
    	qh = qt = 0;
    	sort(border, border + n);
    	n = unique(border, border + n) - border;
    	for (int i = 0; i < n; i++){
    		Border cur = border[i];
    		while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], cur)) --qt;
    		while (qh + 1 < qt&&!check(que[qh], que[qh + 1], cur)) ++qh;
    		que[qt++] = cur;
    	}
    	while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], que[qh])) --qt;
    	while (qh + 1 < qt&&!check(que[qh], que[qh + 1], que[qt - 1])) ++qh;
    	return qt - qh > 2;
    }
    
    Point ps[maxn];
    
    bool judge(double x)
    {
    	for (int i = 0; i < n; i++){
    		border[i].p1 = ps[i];
    		border[i].p2 = ps[(i + 1) % n];
    	}
    	for (int i = 0; i < n; i++){
    		Point vec = border[i].p2 - border[i].p1;
    		vec=vec.rot90().norm();
    		vec = vec*x;
    		border[i].p1 = border[i].p1 + vec;
    		border[i].p2 = border[i].p2 + vec;
    		border[i].setAlpha();
    	}
    	return convexIntersection();
    }
    
    int main()
    {
    	while (cin>>n&&n)
    	{
    		for (int i = 0; i < n; i++){
    			ps[i].read();
    		}
    		double l=0, r=100000000;
    		while (dcmp(r-l)>0){
    			double mid = (l + r) / 2;
    			if (judge(mid)) l = mid;
    			else r = mid;
    		}
    		printf("%.6lf
    ", l);
    	}
    	return 0;
    }
    
  • 相关阅读:
    认识EXTJS
    Ext面向对象开发实践(turn)
    20多个在线操作系统(webOS)一览
    一个成功的博客必须知道的80个博客工具
    163.com免费邮箱背后的传奇故事
    Android ListView的滚动条始终显示并且滚动条样式自定义
    eclipse不格式化注释
    Android横屏竖屏切换
    喝茶的好处
    Android设置Gridview中的内容不滚动,然后控件中的内容随便添加的效果。
  • 原文地址:https://www.cnblogs.com/chanme/p/3710539.html
Copyright © 2011-2022 走看看