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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

hdu1007最近点对问题(分冶java)

發(fā)布時(shí)間:2025/3/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu1007最近点对问题(分冶java) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接
題意就是給若干點(diǎn),求最近點(diǎn)對(duì)問(wèn)題。

  • 首先這題是我很久前看到的,我那時(shí)候用了o(n^2)因?yàn)閿?shù)據(jù)量太大,計(jì)算太多超時(shí)。當(dāng)時(shí)看了別人的分析就說(shuō)分冶當(dāng)時(shí)看代碼太長(zhǎng)也就沒(méi)靜下心看。前天翻了數(shù)據(jù)結(jié)構(gòu)看到分冶算法的最近點(diǎn)問(wèn)題恍然大悟,一下子就懂了。理解了其中的奧秘。
  • 對(duì)于分冶的問(wèn)題,就是一個(gè)問(wèn)題可以拆成若干個(gè)子問(wèn)題,若干個(gè)子問(wèn)題之間沒(méi)有聯(lián)系,并且這個(gè)問(wèn)題的處理方法同樣適用于子問(wèn)題。
    首先上圖

如果用最暴力的方法,那么我們就是要將每?jī)蓚€(gè)點(diǎn)計(jì)算一遍,比較大小。如果有n個(gè)點(diǎn),那么就要計(jì)算n^2次。我們下面進(jìn)行初步優(yōu)化:

取中間點(diǎn),先算出所有左側(cè)點(diǎn)的距離最小值,再算出右側(cè)距離最小值,這兩個(gè)中更小的那個(gè)為min。這個(gè)距離不一定是最短的那個(gè)點(diǎn),因?yàn)橛锌赡茏疃痰哪莻€(gè)點(diǎn)再中間跨越兩邊。

  • 我們思考一下,這個(gè)中間兩點(diǎn)一個(gè)在左,一個(gè)在右,兩個(gè)點(diǎn)的橫坐標(biāo)之差一定小于 min不然他的投影都大于最短,所以我只需要處理中間左右區(qū)間為min里面的點(diǎn)進(jìn)行處理,對(duì)于這些點(diǎn),左右距離是小于min的,如果上下距離大于min,就跳過(guò)不在考慮。
  • 考慮一下計(jì)算量,左側(cè)(n^2) /4 右側(cè) 也是,加起來(lái)是n*n/2,再加上中間的部分?jǐn)?shù)據(jù)。這是一次優(yōu)化的,另外,對(duì)于海量數(shù)據(jù),我們分析其左側(cè),我們也可以把左側(cè)拆成一半,先算左右再算中間,右側(cè)也是如此。并且問(wèn)題可以一直拆分直到不能在拆為止。這個(gè)復(fù)雜度的差距就出來(lái)了。
  • 但是對(duì)于這個(gè)題,如果取x排序分冶事件耗費(fèi)也比較大,這個(gè)可能就是點(diǎn)都大部分聚集在中間,上下間距較大的緣故,我們采用y排序劃分分冶。效率還是很高的。
    附上代碼
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Main {static int n;public static void main(String[] args) throws IOException {StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));//List<node>list=new ArrayList();while(in.nextToken()!=StreamTokenizer.TT_EOF){n=(int)in.nval;if(n==0) {break;}node no[]=new node[n];for(int i=0;i<n;i++){in.nextToken();double x=in.nval;in.nextToken();double y=in.nval;// list.add(new node(x,y));no[i]=new node(x,y);}Arrays.sort(no, com);double min= search(no,0,n-1);out.println(String.format("%.2f", Math.sqrt(min)/2));out.flush();} }private static double search(node[] no, int left,int right) {int mid=(right+left)/2;double minleng=0;if(left==right) {return Double.MAX_VALUE;}else if(left+1==right) {minleng= (no[left].x-no[right].x)*(no[left].x-no[right].x)+(no[left].y-no[right].y)*(no[left].y-no[right].y);}else minleng= min(search(no,left,mid),search(no,mid,right));int ll=mid;int rr=mid+1;while(no[mid].y-no[ll].y<=Math.sqrt(minleng)/2&&ll-1>=left) {ll--;}while(no[rr].y-no[mid].y<=Math.sqrt(minleng)/2&&rr+1<=right) {rr++;}for(int i=ll;i<rr;i++){for(int j=i+1;j<rr+1;j++){double team=0;if(Math.abs((no[i].x-no[j].x)*(no[i].x-no[j].x))>minleng) {continue;}else{ team=(no[i].x-no[j].x)*(no[i].x-no[j].x)+(no[i].y-no[j].y)*(no[i].y-no[j].y);if(team<minleng)minleng=team;}}}return minleng;}private static double min(double a, double b) {// TODO 自動(dòng)生成的方法存根return a<b?a:b;}static Comparator<node>com=new Comparator<node>() {@Overridepublic int compare(node a1, node a2) {// TODO 自動(dòng)生成的方法存根return a1.y-a2.y>0?1:-1;}};static class node{double x;double y;public node(double x,double y){this.x=x;this.y=y;}} }

如果對(duì)后端、爬蟲、數(shù)據(jù)結(jié)構(gòu)算法等感性趣歡迎關(guān)注我的個(gè)人公眾號(hào)交流:bigsai

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的hdu1007最近点对问题(分冶java)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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