HDU 1007Quoit Design(最近点问题)
生活随笔
收集整理的這篇文章主要介紹了
HDU 1007Quoit Design(最近点问题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近點問題:二維平面中有n(n很大)個點,求出距離最近的兩個點思路:因為n的值很大,所以暴力和dp都行不通了吧!分治法就挺好的。將區間一半一半的分開,直到分成只有一個點或兩個點的時候!對于只有兩個點的區間,最小值就是這兩個點的距離,只有一個點的區間,最小值就是無窮大。注意還要考慮合并的時候,可能距離最近的兩個點,分別在左右兩個不同的區間。對于這種情況的處理如下:mid=(ld+rd)/2;ans = min(solve(ld, mid), solve(mid+1, rd));得到兩段區間最小值的最小值 從中間向兩邊尋找,因為我們是按照x坐標排序的,在左區間向左邊尋找的時候如果某一個點的x到中間點x的距離大于ans(否則將這樣的點保存),那么這個點左邊的點就不可能在右區間尋找到相應的點滿足兩個點的距離小于ans的,那么就結束繼續查找(這樣算是一種優化) 同理在右區間向右尋找。。。然后對存儲的節點按照y坐標進行從小到大的排序。 枚舉每兩個點尋找最小的距離
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 #include<algorithm>
6 #define MAX 99999999999999.0
7 using namespace std;
8
9 struct node{
10 double x, y;
11 }nd[100005], ndx[100005];
12
13 bool cmp(node a, node b){
14 if(a.x == b.x) return a.y < b.y;
15 return a.x < b.x;
16 }
17
18 bool cmpy(node a, node b){
19 return a.y < b.y;
20 }
21
22 double dist(node a, node b){
23 return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
24 }
25
26 double solve(int ld, int rd){
27 if(ld == rd) return MAX;
28 if(ld + 1 == rd) return dist(nd[ld], nd[rd]);
29 int mid = (ld+rd)/2;
30 double ans = min(solve(ld, mid), solve(mid+1, rd));
31 int len = 0;
32 for(int i = mid; i>=ld; --i)
33 if(nd[mid].x - nd[i].x <= ans)
34 ndx[len++] = nd[i];
35 else break;
36 for(int i=mid+1; i<=rd; ++i)
37 if(nd[i].x - nd[mid].x <= ans)
38 ndx[len++] = nd[i];
39 else break;
40
41 sort(ndx, ndx+len, cmpy) ;
42 for(int i=0; i<len-1; ++i)
43 for(int j=i+1; j<len; ++j)
44 if(ndx[j].y - ndx[i].y >= ans) break;//這里做一處優化
45 else ans = min(ans, dist(ndx[i], ndx[j]));
46 return ans;
47 }
48
49 int main(){
50 int n;
51 while(scanf("%d", &n) && n){
52 for(int i=0; i<n; ++i)
53 scanf("%lf%lf", &nd[i].x, &nd[i].y);
54 sort(nd, nd+n, cmp);
55 printf("%.2lf\n", solve(0, n-1)/2.0);
56 }
57 return 0;
58 }
?
轉載于:https://www.cnblogs.com/hujunzheng/p/4348418.html
總結
以上是生活随笔為你收集整理的HDU 1007Quoit Design(最近点问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奔驰换电池后如何消除故障
- 下一篇: (三)linux之根文件系统的制作