1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; #define MAX_N (100000 * 2 + 10) const double FINF = 1LL << 60; struct Point { double x, y; int nKind; }; Point pts[MAX_N], ptsY[MAX_N], ptsTemp[MAX_N]; Point ptsSave[MAX_N]; int nNum; bool CmpX(const Point a, const Point b) { return a.x < b.x; }
bool CmpY(const Point a, const Point b) { return a.y < b.y; }
double Dis(Point a, Point b) { if (a.nKind == b.nKind) { return FINF; } else { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } }
double FindMinDis(Point pts[], Point ptsY[], Point ptsTemp[], int nBeg, int nEnd) { if (nBeg == nEnd) { return FINF; } else if (nBeg + 1 == nEnd) { return Dis(pts[nBeg], pts[nEnd]); } else if (nBeg + 2 == nEnd) { return min(min(Dis(pts[nBeg], pts[nBeg + 1]), Dis(pts[nBeg], pts[nEnd])), Dis(pts[nBeg + 1], pts[nEnd])); } else { memcpy(ptsSave + nBeg, ptsY + nBeg, sizeof(Point) * (nEnd - nBeg + 1)); int nMid = (nBeg + nEnd) / 2; int nL = nBeg; int nR = nMid + 1; for (int i = nBeg; i <= nEnd; ++i) { if (ptsY[i].x - pts[nMid].x <= 0) { ptsTemp[nL++] = ptsY[i]; } else { ptsTemp[nR++] = ptsY[i]; } }
double fAns = min(FindMinDis(pts, ptsTemp, ptsY, nBeg, nMid), FindMinDis(pts, ptsTemp, ptsY, nMid + 1, nEnd)); int nK = 1;
for (int i = nBeg; i <= nEnd; ++i) { if (fabs(ptsSave[i].x - pts[nMid].x) <= fAns) { ptsTemp[nK++] = ptsSave[i]; } } for (int i = 1; i < nK; ++i) { for (int j = i + 1; j < nK; ++j) { if (ptsTemp[j].y - ptsTemp[i].y > fAns) { break; } fAns = min(fAns, Dis(ptsTemp[i], ptsTemp[j])); } } return fAns; } }
int main() { int nT; int nN;
scanf("%d", &nT); while (nT--) { scanf("%d", &nN); nNum = nN * 2; for (int i = 0; i < nN; ++i) { scanf("%lf%lf", &pts[i].x, &pts[i].y); pts[i].nKind = 1; } for (int i = nN; i < nNum; ++i) { scanf("%lf%lf", &pts[i].x, &pts[i].y); pts[i].nKind = 2; } memcpy(ptsY, pts, sizeof(Point) * nNum); sort(pts, pts + nNum, CmpX); sort(ptsY, ptsY + nNum, CmpY); printf("%.3f\n", FindMinDis(pts, ptsY, ptsTemp, 0, nNum - 1)); }
return 0; }
|