HDU multi-tenth school field 1007 Closest Pair of Segments - Computational Geometry

Topic links: point I ah ╭ (╯ ^ ╰) ╮

Subject to the effect:

    begging n n nearest line segment of line segments

Problem-solving ideas:

    From the enumeration every two segments of violence
    but to sort the left endpoint of each segment of
    the right end point if the left segment x x and the right segment of the left end point x x value is greater than the a n s years
    directly b r e a k break , can be optimized so that even 19 19 seconds

Core: recent line segment optimization

#include<bits/stdc++.h>
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const double eps = 1e-6;
struct point {
	double x, y;
	point() {}
	point(double X, double Y) {
		x = X, y = Y;
	}
	point operator - (const point &A) {
		return point(x-A.x, y-A.y);
	}
	bool operator < (const point &A)const {
		if(x == A.x) return y < A.y;
		return x < A.x;
	}
} ;

inline int dcmp(double x) {
	if(fabs(x) < eps) return 0;
	return x < 0 ? -1 : 1;
}
inline double cross(point A, point B) {	//	叉积
	return A.x*B.y - B.x*A.y;
}
inline double dot(point A, point B) {	//	点积
	return A.x*B.x + B.y*A.y;
}

double getdis(point a, point b) {	//	两点距离
	return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

struct Line {
	point s, e;
	Line() {}
	Line(point S, point E) {
		s = S, e = E;
	}
	double length() {
		return getdis(s, e);
	}
};

//点到直线距离
inline double point_to_line(point p, Line a) {
	return fabs(cross(p-a.s, a.e-a.s) / a.length());
}

//点到线段距离
inline double point_to_seg(point p, Line a) {
	if(dcmp(dot(p-a.s, a.e-a.s))<0 || dcmp(dot(p-a.e, a.s-a.e))<0)
		return min(getdis(p, a.e), getdis(p, a.s));
	return point_to_line(p, a);
}

//线段到线段的距离
inline double seg_to_seg(Line u, Line v) {
	return min( min(point_to_seg(u.s, v), point_to_seg(u.e, v)),\
	        min( point_to_seg(v.s, u), point_to_seg(v.e, u)) );
}

bool cmp(const Line &u, const Line &v) {
	return u.s < v.s;
}

const int maxn = 1e4 + 5;
int T, n;
Line line[maxn];
int main() {
	scanf("%d", &T);
	while(T--) {
		scanf("%d", &n);
		for(int i=1; i<=n; i++) {
			scanf("%lf%lf", &line[i].s.x, &line[i].s.y);
			scanf("%lf%lf", &line[i].e.x, &line[i].e.y);
			if(line[i].e < line[i].s) swap(line[i].s, line[i].e);
		}
		sort(line+1, line+1+n, cmp);
		double ans = 1e10;
		for(int i=1; i<=n; i++) {
			for(int j=i+1; j<=n; j++) {
				if(dcmp(line[j].s.x-line[i].e.x - ans) > 0) break;
				ans = min(ans, seg_to_seg(line[i], line[j]));
			}
		}
		printf("%.9f\n", ans);
	}
}
Published 221 original articles · won praise 220 · views 20000 +

Guess you like

Origin blog.csdn.net/Scar_Halo/article/details/103827483