• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ACM s1124yy
守りたいものが 強くさせること
博客园    首页    新随笔    联系   管理     

LA 3890 Most Distant Point from the Sea(半平面交)

Most Distant Point from the Sea

【题目链接】Most Distant Point from the Sea

【题目类型】半平面交

&题解:

蓝书279 二分答案,判断平移后的直线的半平面交是否为空.
模板是照着敲的,还有一些地方不是很懂, 应该还要慢慢体会吧

&代码:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

struct Point {
	double x, y;
	Point(double x = 0, double y = 0): x(x), y(y) {}
};

typedef Point Vector;

Vector operator + (const Vector& A, const Vector& B) {return Vector(A.x + B.x, A.y + B.y);}
Vector operator - (const Vector& A, const Vector& B) {return Vector(A.x - B.x, A.y - B.y);}
Vector operator * (const Vector& A, double p) {return Vector(A.x * p, A.y * p);}
double Dot(const Vector& A, const Vector& B) {return A.x * B.x + A.y * B.y;}
double Cross(const Vector& A, const Vector& B) {return A.x * B.y - A.y * B.x;}
double Length(const Vector& A) {return sqrt(Dot(A, A));}
Vector Normal(const Vector& A) {double l = Length(A); return Vector(-A.y / l, A.x / l);}

double PolygonArea(vector<Point> p) {
	int n = p.size();
	double s = 0;
	for(int i = 1; i < n - 1; i++) {
		s += Cross(p[i] - p[0], p[i + 1] - p[0]);
	}
	return s / 2;
}

struct Line {
	Point p, v;
	double ang;
	Line() {}
	Line(Point p, Vector v): p(p), v(v) {ang = atan2(v.y, v.x);}
	bool operator < (const Line& l) const {
		return ang < l.ang;
	}
};

bool OnLeft(const Line& L, const Point& p) {
	return Cross(L.v, p - L.p) > 0;
}

Point GetLineIntersection(const Line& a, const Line& b) {
	Vector u = a.p - b.p;
	double t = Cross(b.v, u) / Cross(a.v, b.v);
	return a.p + a.v * t;
}

const double eps = 1e-6;
vector<Point> HalfplaneIntersection(vector<Line> L) {
	int n = L.size();
	sort(L.begin(), L.end());
	int first, last;
	vector<Point> p(n), ans;
	vector<Line> que(n);
	que[first = last = 0] = L[0];
	for(int i = 1; i < n; i++) {
		while(first < last && !OnLeft(L[i], p[last - 1])) last--;
		while(first < last && !OnLeft(L[i], p[first])) first++;
		que[++last] = L[i];
		if(fabs(Cross(que[last].v, que[last - 1].v)) < eps) {
			last--;
			if(OnLeft(que[last], L[i].p)) que[last] = L[i];
		}
		if(first < last) p[last - 1] = GetLineIntersection(que[last - 1], que[last]);
	}
	while(first < last && !OnLeft(que[first], p[last - 1])) last--;
	if(last - first <= 1) return ans;
	p[last] = GetLineIntersection(que[last], que[first]);
	for(int i = first; i <= last; i++)
		ans.push_back(p[i]);
	return ans;
}

int main() {
	//("E:1.in", "r", stdin);
	int n;
	while(scanf("%d", &n) == 1 && n) {
		vector<Vector> p, v, nor;
		int m, x, y;
		for(int i = 0; i < n; i++) {
			scanf("%d%d", &x, &y);
			p.push_back(Point(x, y));
		}
		if(PolygonArea(p) < 0) reverse(p.begin(), p.end());
		for(int i = 0; i < n; i++) {
			v.push_back(p[(i + 1) % n] - p[i]);
			nor.push_back(Normal(v[i]));
		}
		double left = 0, right = 20000;
		while(right - left > 1e-6) {
			vector<Line> L;
			double mid = left + (right - left) / 2;
			for(int i = 0; i < n; i++)
				L.push_back(Line(p[i] + nor[i]*mid, v[i]));
			vector<Point> poly = HalfplaneIntersection(L);
			if(poly.empty()) right = mid;
			else left = mid;
		}
		printf("%f\n", left);
	}
	return 0;
}
posted @ 2017-05-02 01:48  s1124yy  阅读(207)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3