日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU1007 查找平面最近点对

發布時間:2025/6/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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點與下面正方形的四個頂點距離小于δ,則和δSLSR的最小點對距離相矛盾。因此對于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)?????//記錄和mid位置點小于d的點的位置??
  • ????????????a[k++]?=?i;????????//注意這里記錄的是位置號??
  • ????}??
  • ????sort(a,a+k,cmpy);????//按y坐標排序??
  • ????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);????//按x坐標排序??
  • ????????printf("%.2f\n",cloest(0,n-1)?/?2);??
  • ????}??
  • ????return?0;??
  • }?
  • 總結

    以上是生活随笔為你收集整理的HDU1007 查找平面最近点对的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。