分治法求最近對問題
阿新 • • 發佈:2018-12-03
首先感謝博主https://www.cnblogs.com/zuoyou151/p/9059903.html,讓我收穫很多,今天感覺很困,狀態不佳,解析與講解會改天補上,註明:我這裡採用遞迴時是左閉右開區間,而博主採用的左閉右閉。
還有感謝“NX”童鞋為我調好VS2017,之前因為環境問題一直裝不上,不過VS2017的除錯是真的好用啊,哈哈!
Code
#include <algorithm> #include <iostream> #include <cmath> #define INF 0x3f3f3f3f using namespace std; const int maxn = 1005; typedef struct Point { double x; double y; } point; int n; point p[maxn]; double dist(point p1, point p2) { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); } bool cmp(point p1, point p2) { return p1.x < p2.x; } bool cmp2(point p1, point p2) { return p1.y < p2.y; } double solve(int left, int right) { //cout << left << ", " << right << endl; if (right - left == 1) { return INF; } if (right - left == 2) { return dist(p[left], p[right - 1]); } int mid = (left + right) / 2; double d1 = solve(left, mid); double d2 = solve(mid, right); double d = min(d1, d2); int l = left; while (p[l].x < p[mid].x - mid && l < right) l++; int r = right - 1; while (p[r].x > p[mid].x + d && r >= left) r--; sort(p + l, p + r + 1, cmp2); double d3; for (int i = l; i <= r; i++) { for (int j = i + 1; j <= r; j++) { d = min(d, dist(p[i], p[j])); } } return d; } int main() { cin >> n; for (int i = 0; i < n; i++) cin >> p[i].x >> p[i].y; sort(p, p + n, cmp); cout << solve(0, n) << endl; return 0; }