杭電ACM第1007題——Quoit Design
阿新 • • 發佈:2019-02-20
#include <iostream> #include <algorithm> #include <cmath> using namespace std; const int SIZE = 100005; typedef struct { double x; double y; }point; point p[SIZE], c[SIZE]/*用作輔助陣列*/; double getDistance(point &a, point &b){ /*求得兩點之間的距離*/ return sqrt(pow(a.x - b.x, 2.0) + pow(a.y - b.y, 2.0)); } bool cmpx(point &a, point &b){ if (a.x == b.x) return a.y < b.y; return a.x < b.x; } bool cmpy(point &a, point &b){ if (a.y == b.y) return a.x < b.x; return a.y < b.y; } inline double min(double a, double b, double c){ a = a< b ? a : b; a = a< c ? a : c; return a; } inline double minDist(double a, double b){ a=a<b?a:b; return a; } double divide_conquer(int low, int high) {/*分治法求最小距離*/ double dis; if (low==high) return 0; else if (low+1 == high) /*兩個數*/ dis = getDistance(p[low], p[high]); else if (low+2 == high){/*三個數*/ double temp1, temp2, temp3; temp1 = getDistance(p[low], p[low + 1]); temp2 = getDistance(p[low + 1], p[high]); temp3 = getDistance(p[low], p[high]); dis = min(temp1, temp2, temp3); } else{ /*大於三個數的情況*/ double leftmin, rightmin; int mid = (low + high) / 2; int k= 0,i, j; leftmin = divide_conquer(low, mid); /*求得左邊部分的最小值*/ rightmin = divide_conquer(mid + 1, high); /*求得右邊部分的最小值*/ dis = minDist(leftmin, rightmin); /*下面從所有座標點中找出所有x在leftCoord到rightCoord之間的點*/ for (i = low; i <=high; i++){ if (fabs(p[i].x-p[mid].x)<dis) c[k++]=p[i]; } sort(c, c + k, cmpy); /*找到的點再從小到大按照y排序一次*/ for (i = 0; i < k; i++){ for (j = i+1;j<k&&p[j].y-p[i].y<dis ; j++){ dis= minDist(dis,getDistance(c[i], c[j])); } } } return dis; } int main (){ int n; while (cin >> n && n != 0){ double result = 0; for (int i = 0; i < n; i++){ cin >> p[i].x >> p[i].y; } sort (p, p + n, cmpx); result = divide_conquer(0, n - 1); printf("%.2lf\n", result / 2); } return 0; }