当前位置: 代码迷 >> 综合 >> POJ 3525 Most Distant Point from the Sea 二分+半平面交
  详细解决方案

POJ 3525 Most Distant Point from the Sea 二分+半平面交

热度:33   发布时间:2024-01-13 17:18:17.0


题目就是求多变形内部一点。 使得到任意边距离中的最小值最大。

那么我们想一下,可以发现其实求是看一个圆是否能放进这个多边形中。

那么我们就二分这个半径r,然后将多边形的每条边都往内退r距离。

求半平面交看是否存在解即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 111111
#define MAXM 211111
#define PI acos(-1.0)
#define eps 1e-8
#define INF 1000000001
using namespace std;
int dblcmp(double d)
{if (fabs(d) < eps) return 0;return d > eps ? 1 : -1;
}
struct point
{double x, y;point(){}point(double _x, double _y):x(_x), y(_y){};void input(){scanf("%lf%lf",&x, &y);}double dot(point p){return x * p.x + y * p.y;}double distance(point p){return hypot(x - p.x, y - p.y);}point sub(point p){return point(x - p.x, y - p.y);}double det(point p){return x * p.y - y * p.x;}bool operator == (point a)const{return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;}bool operator < (point a)const{return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;}}p[MAXN];
struct line
{point a,b;line(){}line(point _a,point _b){a=_a;b=_b;}bool parallel(line v){return dblcmp(b.sub(a).det(v.b.sub(v.a))) == 0;}point crosspoint(line v){double a1 = v.b.sub(v.a).det(a.sub(v.a));double a2 = v.b.sub(v.a).det(b.sub(v.a));return point((a.x * a2 - b.x * a1) / (a2 - a1), (a.y * a2 - b.y * a1) / (a2 - a1));}bool operator == (line v)const{return (a == v.a) && (b == v.b);}
};
struct halfplane:public line
{double angle;halfplane(){}//表示向量 a->b逆时针(左侧)的半平面halfplane(point _a, point _b){a = _a;b = _b;}halfplane(line v){a = v.a;b = v.b;}void calcangle(){angle = atan2(b.y - a.y, b.x - a.x);}bool operator <(const halfplane &b)const{return angle < b.angle;}
};
struct polygon
{int n;point p[MAXN];line l[MAXN];double area;void getline(){for (int i = 0; i < n; i++){l[i] = line(p[i], p[(i + 1) % n]);}}void getarea(){area = 0;int a = 1, b = 2;while(b <= n - 1){area += p[a].sub(p[0]).det(p[b].sub(p[0]));a++;b++;}area = fabs(area) / 2;}
}convex;
struct halfplanes
{int n;halfplane hp[MAXN];point p[MAXN];int que[MAXN];int st, ed;void push(halfplane tmp){hp[n++] = tmp;}void unique(){int m = 1, i;for (i = 1; i < n;i++){if (dblcmp(hp[i].angle - hp[i - 1].angle))hp[m++] = hp[i];else if (dblcmp(hp[m - 1].b.sub(hp[m - 1].a).det(hp[i].a.sub(hp[m - 1].a)) > 0))hp[m - 1] = hp[i];}n = m;}bool halfplaneinsert(){int i;for (i = 0; i < n; i++) hp[i].calcangle();sort(hp, hp + n);unique();que[st = 0] = 0;que[ed = 1] = 1;p[1] = hp[0].crosspoint(hp[1]);for (i = 2; i < n; i++){while (st < ed && dblcmp((hp[i].b.sub(hp[i].a).det(p[ed].sub(hp[i].a)))) < 0) ed--;while (st < ed && dblcmp((hp[i].b.sub(hp[i].a).det(p[st + 1].sub(hp[i].a)))) < 0) st++;que[++ed] = i;if (hp[i].parallel(hp[que[ed - 1]])) return false;p[ed] = hp[i].crosspoint(hp[que[ed - 1]]);}while (st < ed && dblcmp(hp[que[st]].b.sub(hp[que[st]].a).det(p[ed].sub(hp[que[st]].a))) < 0) ed--;while (st < ed && dblcmp(hp[que[ed]].b.sub(hp[que[ed]].a).det(p[st + 1].sub(hp[que[ed]].a))) < 0) st++;if (st + 1 >= ed)return false;return true;}void getconvex(polygon &con){p[st] = hp[que[st]].crosspoint(hp[que[ed]]);con.n = ed - st + 1;int j = st, i = 0;for (; j <= ed; i++, j++){con.p[i] = p[j];}}
}h;
int T;
int n;
line getmove(point a, point b, double mid)
{double x = a.x - b.x;double y = a.y - b.y;double L = a.distance(b);point ta = point(mid * y / L + a.x, a.y - mid * x / L);point tb = point(mid * y / L + b.x, b.y - mid * x / L);return line(ta, tb);
}
bool check(double mid)
{h.n = 0;for(int i = 0; i < n; i++){line tmp = getmove(p[i], p[(i + 1) % n], mid);h.push(halfplane(tmp));}return h.halfplaneinsert();
}
int main()
{int cas = 0;while(scanf("%d", &n) != EOF && n){for(int i = 0; i < n; i++) p[i].input();double low = 0, high = INF;for(int i = 0; i < 100; i++){double mid = (low + high) / 2;if(check(mid)) low = mid;else high = mid;}printf("%.6f\n", low);}return 0;
}



  相关解决方案