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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU1007 查找平面最近点对

發(fā)布時間:2025/6/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU1007 查找平面最近点对 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
求點(diǎn)集中的最近點(diǎn)對有以下兩種方法:

設(shè)p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n個點(diǎn)構(gòu)成的集合S,設(shè)計(jì)算法找出集合S中距離最近的點(diǎn)對。

?OJ題目:HDU1007http://acm.hdu.edu.cn/showproblem.php?pid=1007

1、蠻力法(適用于點(diǎn)的數(shù)目比較小的情況下)

1)算法描述:已知集合S中有n個點(diǎn),一共可以組成n(n-1)/2對點(diǎn)對,蠻力法就是對這n(n-1)/2對點(diǎn)對逐對進(jìn)行距離計(jì)算,通過循環(huán)求得點(diǎn)集中的最近點(diǎn)對:

2、分治法

1)算法描述:已知集合S中有n個點(diǎn),分治法的思想就是將S進(jìn)行拆分,分為2部分求最近點(diǎn)對。算法每次選擇一條垂線L,將S拆分左右兩部分為SL和SR,L一般取點(diǎn)集S中所有點(diǎn)的中間點(diǎn)的x坐標(biāo)來劃分,這樣可以保證SL和SR中的點(diǎn)數(shù)目各為n/2

(否則以其他方式劃分S,有可能導(dǎo)致SL和SR中點(diǎn)數(shù)目一個為1,一個為n-1,不利于算法效率,要盡量保持樹的平衡性)

依次找出這兩部分中的最小點(diǎn)對距離:δLδR,記SL和SR中最小點(diǎn)對距離δ = min(δLδR),如圖1:

?

以L為中心,δ為半徑劃分一個長帶,最小點(diǎn)對還有可能存在于SL和SR的交界處如下圖2左圖中的虛線帶,p點(diǎn)和q點(diǎn)分別位于SL和SR的虛線范圍內(nèi),在這個范圍內(nèi),p點(diǎn)和q點(diǎn)之間的距離才會小于δ,最小點(diǎn)對計(jì)算才有意義。

?

Figure 2

?

對于SL虛框范圍內(nèi)的p點(diǎn),在SR虛框中與p點(diǎn)距離小于δ的頂多只有六個點(diǎn),就是圖二右圖中的2個正方形的6的頂點(diǎn)。這個可以反推證明,如果右邊這2個正方形內(nèi)有7個點(diǎn)與p點(diǎn)距離小于δ,例如q點(diǎn),則q點(diǎn)與下面正方形的四個頂點(diǎn)距離小于δ,則和δSLSR的最小點(diǎn)對距離相矛盾。因此對于SL虛框中的p點(diǎn),不需求出p點(diǎn)和右邊虛線框內(nèi)所有點(diǎn)距離,只需計(jì)算SR與p點(diǎn)y坐標(biāo)距離最近的6個點(diǎn),就可以求出最近點(diǎn)對,節(jié)省了比較次數(shù)。

(否則的話,最壞情形下,SR虛框中有可能會有n/2個點(diǎn),對于SL虛框中的p點(diǎn)每次要比較n/2次,浪費(fèi)了算法的效率

[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);?????//遞歸求左部分最近點(diǎn)距離??
  • ????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位置點(diǎn)小于d的點(diǎn)的位置??
  • ????????????a[k++]?=?i;????????//注意這里記錄的是位置號??
  • ????}??
  • ????sort(a,a+k,cmpy);????//按y坐標(biāo)排序??
  • ????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坐標(biāo)排序??
  • ????????printf("%.2f\n",cloest(0,n-1)?/?2);??
  • ????}??
  • ????return?0;??
  • }?
  • 總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。