题目:http://poj.org/problem?id=3608
View Code
#include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> #define clr(a,b) memset(a,b,sizeof(a)) #define sqr(x) ((x)*(x)) using namespace std; const double eps = 1e-8; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const int N = 10000+10; int dcmp(double x){ if (x < -eps) return -1; else return x > eps; } struct cpoint { double x, y; cpoint(){} cpoint(double x, double y):x(x), y(y){} void get() { scanf("%lf%lf", &x, &y); } bool operator == (const cpoint& u)const{ return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0; } }; double cross(cpoint o, cpoint p, cpoint q){ return (p.x-o.x)*(q.y-o.y)-(q.x-o.x)*(p.y-o.y); } double dot(cpoint o, cpoint p, cpoint q){ return (p.x-o.x)*(q.x-o.x)+(p.y-o.y)*(q.y-o.y); } double dis(cpoint p, cpoint q){ return sqrt(sqr(p.x-q.x) + sqr(p.y-q.y)); } double dissqr(cpoint p, cpoint q){ return sqr(p.x-q.x) + sqr(p.y-q.y); } bool PointOnSegment(cpoint p0, cpoint p1, cpoint p2){ return dcmp(cross(p0, p1, p2)) == 0 && dcmp(dot(p0, p1, p2)) <= 0; } double PointToLine(cpoint p0, cpoint p1, cpoint p2, cpoint &cp){ double d = dis(p1, p2); double s = cross(p1, p2, p0) / d; cp.x = p0.x + s * (p2.y - p1.y) / d; cp.y = p0.y - s * (p2.x - p1.x) / d; return fabs(s); } cpoint bp; int PolarCmp(const cpoint &p1, const cpoint &p2){ int u = dcmp(cross(bp, p1, p2)); return u > 0 || (u==0 && dcmp(dissqr(bp, p1)-dissqr(bp, p2))<0); } void graham(cpoint pin[], int n, cpoint ch[], int &m){ int i, j, k, u, v; memcpy(ch, pin, n*sizeof(cpoint)); for (i=k=0; i<n; i++){ u = dcmp(ch[i].x - ch[k].x); v = dcmp(ch[i].y - ch[k].y); if (v < 0 || (v==0 && u<0)) k = i; } bp = ch[k]; sort(ch, ch+n, PolarCmp); n = unique(ch, ch+n) - ch; if (n <= 1) { m = n; return ; } if (dcmp(cross(ch[0],ch[1],ch[n-1]))==0){ m = 2; ch[1] = ch[n-1]; return ; } ch[n++] = ch[0]; for (i=1, j=2; j<n; j++){ while (i>0 && dcmp(cross(ch[i-1], ch[i], ch[j]))<=0)i--; ch[++i] = ch[j]; } m = i; } double PointToSeg(cpoint p0, cpoint p1, cpoint p2){ cpoint cp; double d = PointToLine(p0, p1, p2, cp); if (PointOnSegment(cp, p1, p2)) return d; else return min(dis(p0, p1), dis(p0, p2)); } double DisPallSeg(cpoint p0, cpoint p1, cpoint p2, cpoint p3){ return min(min(PointToSeg(p0, p2, p3), PointToSeg(p1, p2, p3)), min(PointToSeg(p2, p0, p1), PointToSeg(p3, p0, p1))); } void anticlockwise(cpoint cp[], int n){ for (int i=0; i<n-2; i++){ double t = cross(cp[i], cp[i+1], cp[i+2]); if (dcmp(t) > 0) return ; if (dcmp(t) < 0) { reverse(cp, cp+n); return ; } } } double rotating(cpoint ch1[], int n, cpoint ch2[], int m){ int p = 0, q = 0; for (int i=0; i<n; i++) if (dcmp(ch1[i].y - ch1[p].y) < 0) p = i; for (int i=0; i<m; i++) if (dcmp(ch2[i].y - ch2[q]. y) > 0) q = i; ch1[n] = ch1[0], ch2[m] = ch2[0]; double tmp, res = 1e99; for (int i=0; i<n; i++){ while ((tmp = cross(ch1[p],ch1[p+1],ch2[q+1])- cross(ch1[p],ch1[p+1],ch2[q])) > eps) q = (q + 1) % m; if (dcmp(tmp) < 0) res = min(res, PointToSeg(ch2[q], ch1[p], ch1[p+1])); else res = min(res, DisPallSeg(ch1[p], ch1[p+1], ch2[q], ch2[q+1])); p = (p + 1) % m; } return res; } void solve(cpoint ch1[], int n, cpoint ch2[], int m){ anticlockwise(ch1, n); anticlockwise(ch2, m); double ans = min(rotating(ch1, n, ch2, m), rotating(ch2, m, ch1, n)); printf("%.5f\n", ans); } cpoint p[N], q[N]; int main() { //freopen("D:/a.txt", "r", stdin); int n, m; while (~scanf("%d%d", &n, &m)) { if (n==0 && m==0) break; for (int i=0; i<n; i++) p[i].get(); for (int i=0; i<m; i++) q[i].get(); solve(p, n, q, m); } return 0; }