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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

转载 - 最近对问题

發布時間:2023/11/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转载 - 最近对问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  之前看過,可是當時沒有細看,今天在網上搜了一下,看了一下別人的思路,畢竟這也是一類問題的經典。過一段時間再將自己對其認識總結。現在先轉載別人的思路。

  出處:http://blog.csdn.net/sd6264456/article/details/9318861

  給n個點的坐標,求距離最近的一對點之間距離的一半。第一行是一個數n表示有n個點,接下來n行是n個點的x坐標和y坐標,實數。
???? 這個題目其實就是求最近點對的距離。主要思想就是分治。先把n個點按x坐標排序,然后求左邊n/2個和右邊n/2個的最近距離,最后合并。合并要重點說一下,比較麻煩。
???? 首先,假設點是n個,編號為1到n。我們要分治求,則找一個中間的編號mid,先求出1到mid點的最近距離設為d1,還有mid+1到n的最近距離設為 d2。這里的點需要按x坐標的順序排好,并且假設這些點中,沒有2點在同一個位置。(若有,則直接最小距離為0了)。
???? 然后,令d為d1, d2中較小的那個點。如果說最近點對中的兩點都在1-mid集合中,或者mid+1到n集合中,則d就是最小距離了。但是還有可能的是最近點對中的兩點分 屬這兩個集合,所以我們必須先檢測一下這種情況是否會存在,若存在,則把這個最近點對的距離記錄下來,去更新d。這樣我們就可以得道最小的距離d了。
??? 關鍵是要去檢測最近點對,理論上每個點都要和對面集合的點匹配一次,那效率還是不能滿足我們的要求。所以這里要優化。怎么優化呢?考慮一下,假如以我們所 選的分割點mid為界,如果某一點的橫坐標到點mid的橫坐標的絕對值超過d1并且超過d2,那么這個點到mid點的距離必然超過d1和d2中的小者,所 以這個點到對方集合的任意點的距離必然不是所有點中最小的。
??? 所以我們先把在mid為界左右一個范圍內的點全部篩選出來,放到一個集合里。篩選好以后,當然可以把這些點兩兩求距離去更新d了,不過這樣還是很慢,萬一 滿足條件的點很多呢。這里還得繼續優化。首先把這些點按y坐標排序。假設排序好以后有cnt個點,編號為0到cnt-1。那么我們用0號去和1到cnt- 1號的點求一下距離,然后1號和2到cnt-1號的點求一下距離。。。如果某兩個點y軸距離已經超過了d,這次循環就可以直接break了,開始從下一個 點查找了.

?

1 #include <cmath> 2 #include <algorithm> 3 #include <iostream> 4 #include <string.h> 5 using namespace std; 6 struct node 7 { 8 double x,y; 9 }a[100005]; 10 int c[100005]; 11 double cmpy(int t1,int t2) 12 { 13 return a[t1].y<a[t2].y; 14 } 15 bool cmp(node t1,node t2) 16 { 17 return t1.x<t2.x; 18 } 19 double dis(node t1,node t2) 20 { 21 return sqrt((t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y)); 22 } 23 double min(double t1,double t2) 24 { 25 return t1<t2?t1:t2; 26 } 27 double find(int left,int right) 28 { 29 if(left+1==right) 30 return dis(a[left],a[right]); 31 if(left+2==right) 32 return min(dis(a[left],a[right]),min(dis(a[left],a[left+1]),dis(a[left+1],a[right]))); 33 int mid=(left+right)>>1; 34 double ans=min(find(left,mid),find(mid+1,right)); 35 int i,j,cnt=0; 36 for(i=left;i<=right;i++) 37 { 38 if(a[i].x>=a[mid].x-ans&&a[i].x<=a[mid].x+ans) 39 c[cnt++]=i; 40 } 41 sort(c,c+cnt,cmpy); 42 for(i=0;i<cnt;i++) 43 { 44 for(j=i+1;j<cnt;j++) 45 { 46 if(a[c[j]].y-a[c[i]].y>=ans) 47 break; 48 ans=min(ans,dis(a[c[i]],a[c[j]])); 49 } 50 } 51 return ans; 52 53 } 54 int main() 55 { 56 int n,i; 57 while(cin>>n,n) 58 { 59 for(i=0;i<n;i++) 60 { 61 cin>>a[i].x>>a[i].y; 62 } 63 std::sort(a,a+n,cmp); 64 printf("%.2lf\n",find(0,n-1)/2); 65 } 66 return 0; 67 }

?

?

?

轉載于:https://www.cnblogs.com/sineatos/p/3229107.html

總結

以上是生活随笔為你收集整理的转载 - 最近对问题的全部內容,希望文章能夠幫你解決所遇到的問題。

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