生活随笔
收集整理的這篇文章主要介紹了
HDU1007 查找平面最近点对
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
求點集中的最近點對有以下兩種方法:
設p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n個點構成的集合S,設計算法找出集合S中距離最近的點對。
?OJ題目:HDU1007http://acm.hdu.edu.cn/showproblem.php?pid=1007
1、蠻力法(適用于點的數目比較小的情況下)
1)算法描述:已知集合S中有n個點,一共可以組成n(n-1)/2對點對,蠻力法就是對這n(n-1)/2對點對逐對進行距離計算,通過循環求得點集中的最近點對:
2、分治法
1)算法描述:已知集合S中有n個點,分治法的思想就是將S進行拆分,分為2部分求最近點對。算法每次選擇一條垂線L,將S拆分左右兩部分為SL和SR,L一般取點集S中所有點的中間點的x坐標來劃分,這樣可以保證SL和SR中的點數目各為n/2,
(否則以其他方式劃分S,有可能導致SL和SR中點數目一個為1,一個為n-1,不利于算法效率,要盡量保持樹的平衡性)
依次找出這兩部分中的最小點對距離:δL和δR,記SL和SR中最小點對距離δ = min(δL,δR),如圖1:
?
以L為中心,δ為半徑劃分一個長帶,最小點對還有可能存在于SL和SR的交界處,如下圖2左圖中的虛線帶,p點和q點分別位于SL和SR的虛線范圍內,在這個范圍內,p點和q點之間的距離才會小于δ,最小點對計算才有意義。
?
Figure 2
?
對于SL虛框范圍內的p點,在SR虛框中與p點距離小于δ的頂多只有六個點,就是圖二右圖中的2個正方形的6的頂點。這個可以反推證明,如果右邊這2個正方形內有7個點與p點距離小于δ,例如q點,則q點與下面正方形的四個頂點距離小于δ,則和δ為SL和SR中的最小點對距離相矛盾。因此對于SL虛框中的p點,不需求出p點和右邊虛線框內所有點距離,只需計算SR中與p點y坐標距離最近的6個點,就可以求出最近點對,節省了比較次數。
(否則的話,最壞情形下,在SR虛框中有可能會有n/2個點,對于SL虛框中的p點,每次要比較n/2次,浪費了算法的效率)
[cpp] view plaincopy
#include?<iostream>??#include?<cstring>??#include?<algorithm>??#include?<cstdio>??#include?<cmath>??using?namespace?std;??struct?point??{??????double?x,y;??}p[100005];??int?a[100005];??int?cmpx(const?point?&a,const?point?&b)??{??????return?a.x?<?b.x;??}??int?cmpy(const?int?&a,const?int?&b)??{??????return?p[a].y?<?p[b].y;??}??double?dis(int?a,int?b)??{??????return?sqrt((p[a].x?-?p[b].x)?*?(p[a].x?-?p[b].x)?+?(p[a].y?-?p[b].y)?*?(p[a].y?-?p[b].y));??}??double?min(double?x,double?y)??{??????return?x?<?y???x?:?y;??}??double?cloest(int?left,?int?right)??{??????if(left?==?right)??????????return?1000000;??????if(left?+?1?==?right)??????????return?dis(left,right);??????int?mid?=?(left?+?right)?>>?1;??????double?d1?=?cloest(left,mid);???????????double?d2?=?cloest(mid+1,right);?????????double?d?=?min(d1,d2);??????int?i,j,k?=?0;??????for(?i?=?left?;?i?<=?right;?i++?)??????{??????????if(fabs(p[mid].x?-?p[i].x)?<?d)???????????????????a[k++]?=?i;??????????????}??????sort(a,a+k,cmpy);??????????for(?i?=?0;?i?<?k?-?1;?i++?)???????????{??????????for(?j?=?i+1;?j?<?i?+?7?&&?j?<?k;?j++?)??????????{??????????????if(p[a[j]].y?-?p[a[i]].y?>=?d)??????????????????break;??????????????d?=?min(d,dis(a[i],a[j]));??????????}??????}??????return?d;????}??int?main()??{??????int?i,n;??????while(scanf("%d",&n)?!=?0)??????{??????????if(!n)??????????????break;??????????for(?i?=?0;?i?<?n;?i++?)??????????{??????????????scanf("%lf?%lf",&p[i].x,&p[i].y);??????????}??????????sort(p,p+n,cmpx);??????????????printf("%.2f\n",cloest(0,n-1)?/?2);??????}??????return?0;??}?
總結
以上是生活随笔為你收集整理的HDU1007 查找平面最近点对的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。