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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P1429-平面最近点对(加强版)【分治】

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P1429-平面最近点对(加强版)【分治】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P1429


題目大意

平面上nnn個點,求最近點對


解題思路

考慮分治求最近點對,首先將平行于yyy軸將平面穿過xxx左邊的中位數分割成兩半,現在最近點對有三種可能,

  • 在分割線左邊
  • 在分割線右邊
  • 穿過分割線
  • 我們知道1和2可以用分治到兩邊計算,考慮如何求情況3。暴力枚舉對數肯定會TLETLETLE,考慮優化,假設我們已經知道1和2的最小解d1,d2d1,d2d1,d2了,我們有d=min{d1,d2}d=min\{d1,d2\}d=min{d1,d2},那么我們可以以分割線為對稱軸做一個2d?d2d*d2d?d的矩形,最近點對的兩個點一定在這個矩形內。

    這樣計算為什么可以優化算法?因為矩陣內的點數是常數級別的,首先我們可以由分割線分割成兩個小正方形,我們知道正方形內的點距離一定不小于ddd,那么一個正方形內最多只有常數級別的點數(好像是3個的樣子)

    所以時間復雜度O(nlog?n)O(n\log n)O(nlogn)


    codecodecode

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=2e5+10; int n,p[N],c[N]; double x[N],y[N]; bool cmp(int a,int b) {return (x[a]==x[b])?(y[a]<y[b]):(x[a]<x[b]);} bool cMp(int a,int b) {return y[a]<y[b];} double get_dis(int a,int b) {return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));} double Solve(int l,int r){double d=1e18;if(l==r)return d;if(l+1==r)return get_dis(p[l],p[r]);int mid=(l+r)>>1;double d1=Solve(l,mid);double d2=Solve(mid+1,r);d=min(d1,d2);int tot=0;for(int i=l;i<=r;i++)if(fabs(x[p[i]]-x[p[mid]])<=d)c[++tot]=p[i];sort(c+1,c+1+tot,cMp);for(int i=0;i<tot;i++){for(int j=i+1;j<=tot;j++){if(y[c[j]]-y[c[i]]>=d)break;double D=get_dis(c[i],c[j]);d=min(d,D);}}return d; } int main() {scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lf%lf",&x[i],&y[i]);p[i]=i;}sort(p+1,p+1+n,cmp);printf("%.4lf",Solve(1,n)); }

    總結

    以上是生活随笔為你收集整理的P1429-平面最近点对(加强版)【分治】的全部內容,希望文章能夠幫你解決所遇到的問題。

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