Openjudge 最近點對問題

2021-08-17 17:04:50 字數 1352 閱讀 2599

平面最近點對問題,經典分治問題。

按照點的x座標排序做預處理。

點集合s按照x座標平分為l,r兩組點,分別得到每組組內點的最小距離dl和dr,d = min(dl,dr),然後記橫座標距分割線距離小於d的點集為r,計算r內點與點的距離,與d比較,得到s內點的最小距離。

細節再與計算r內點與點的距離。

再從l組和r組得到分治結果後,對l和r內的點對y進行歸併排序(複雜度為n),並篩查出屬於r的點,這個排序後的序列記為r。這時候,有個trick。

任意乙個點p,只要和他再r內的之前6個,之後6個點計算距離並比較,就足夠了。證明參見《演算法設計與分析》(屈婉玲)。

#include#include#include#include#includeusing namespace std;

struct point;

point temp[201000];

double distance(point a, point b)

double min_dis(point a, point aux, int l, int r)

int mid = (l + r)/2;

delta = min(min(delta, min_dis(a, aux, l, mid)), min_dis(a, aux, mid + 1, r));

int lp = l, rp = mid + 1, auxp = l;

while (lp <= mid && rp <= r)

else

} while (lp <= mid)

while (rp <= r)

int t = 0;

for (int i = l; i <= r; i ++)

} for (int i = 0; i < t; i ++)

for (int j = -1; j >= -6 && (i + j ) >= 0; j --)

} memcpy(&a[l], &aux[l], sizeof(point) * (r - l + 1));

// printf("%d %d %lf\n", l, r, delta);

return delta;

}int main(), aux[201000] = {};

while (cin >> n)

sort(a, a + n, (point p1, point p2)->bool );

for (int i = 0; i < n; i ++)

double dis = min_dis(a, aux, 0, n - 1);

printf("%.3lf", dis);

} return 0;

}

最近點對問題

在n n 1 個點的集合中尋找最近點對。即求任意兩點的歐幾里得距離的最小值。1 最簡單的暴力搜尋演算法,時間複雜對為o n n 2 這裡主要考慮分治演算法,執行時間的遞迴式為t n 2 t n 2 o n 時間複雜度為o n lgn 演算法思想 將集合中的點按x座標排序,我們可以想象一條垂直的直線將...

最近點對問題

在二維平面上的n個點中,如何快速的找出最近的一對點,就是最近點對問題。一種簡單的想法是暴力列舉每兩個點,記錄最小距離,顯然,時間複雜度為o n 2 在這裡介紹一種時間複雜度為o nlognlogn 的演算法。其實,這裡用到了分治的思想。將所給平面上n個點的集合s分成兩個子集s1和s2,每個子集中約有...

最近點對問題

最近點對問題,是分治法的乙個典型應用,可以作為分治法入門的乙個切入點。最近點對問題的描述比較簡單,在二維平面中,給定一堆點,求距離最近的一對點,思路是,講這一堆點分為兩部分,左域與右域,如何劃分左域右域呢?我們知道,這一堆點,每乙個點都有其橫座標,假如有十個點,對應十個橫座標,我們就取其中間數,然後...