• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅信:勤能補拙

            2011分治-平面最近點對(附C++源代碼)

            求平面最近點對的核心思想乃是二分,用遞歸實現。具體操作如下:

                 若點的個數很少(比如小于3或者小于5),就直接枚舉。

                 如點的個數很多,按現將所有點按X排序,并按X坐標平均的分成左右兩個部分(假設分割線為X=nx),分別求出兩邊的最短距離minl與minr并令ans=min(minl,minr)。

                 求出左右兩邊的最小值之后,剩下的工作就是合并。易見若該點集存在點對(a,b)的最近距離小于ans,則a,b一定分別在x=nx的兩邊,切nx-a.x與nx-b.x的絕對值肯定小于ans。

                 據此我們可以將點集中所有X值在(nx-ans,nx+ans)的點都選出來,那么滿足條件的(a,b)肯定都在其中。

                 易見若存在(a,b)兩點他們之間的距離小于ans,那么a.y-b.y的絕對值也肯定小于ans。

                 綜上存在(a,b)兩點他們之間的距離小于ans那,(a,b)一定在一個長為2*ans寬為ans的矩形之中。而 且這個矩形被X=nx平分成兩個ans*ans的矩形,由于無論是在左邊還是在右邊,任意兩點的之間的距離總是小于等于ans的,所以兩個ans*ans 的矩形中最多只有4個點(分別在四個頂點上),長為2*ans寬為ans的矩形最多有8個點。

                 據此我們將所有X值在(nx-ans,nx+ans)的點按他們的Y值進行排序。依次看每個點與它之后的7個點的距離是否小于ans,若小于則更新ans,最后求出來的結果就是平面最近點對的距離。保留產生該距離的兩個點即可得到最近點對。

                 練手題目:Pku2107,Vijos1012

            附C++代碼(Pku2107):

            #include <iostream>
            #include <cmath>

            const long maxsize = 100000;

            typedef struct 

            double x, y; 
            } PointType;

            long list[maxsize], listlen,n;
            PointType point[maxsize];

            int sortcmp(const void *,const void *); 
            double dis(PointType,PointType);
            double getmin(double,double);
            int listcmp(const void *,const void *); 
            double shortest(long,long);
            int init(void);

            int main() 

            while (init())
               printf("%.2lf\n",shortest(0, n - 1)/2);    
            return 0;
            }

            int sortcmp(const void *a, const void *b) 

            if (((PointType*)a)->x < ((PointType*)b)->x)    
               return -1;   
            else 
               return 1; 
            }

            double dis(PointType a, PointType b) 

            return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); 
            }

            double getmin(double a, double b) 

            return a<b?a:b;
            }

            int listcmp(const void *a, const void *b) 

            if (point[*(int*)a].y < point[*(int*)b].y)    
               return -1;   
            else 
               return 1; 
            }

            double shortest(long l, long r) 

            if (r - l == 1) 
               return dis(point[l], point[r]);   
            if (r - l == 2)    
               return getmin(getmin(dis(point[l], point[l+1]), dis(point[l], point[r])), dis(point[l+1], point[r]));   
            long i, j, mid = (l + r) >> 1;   
            double curmin = getmin(shortest(l, mid), shortest(mid + 1, r));   
            listlen = 0;   
            for (i = mid; i >= l && point[mid+1].x - point[i].x <= curmin; i --)    
               list[listlen++] = i;   
            for (i = mid + 1; i <= r && point[i].x - point[mid].x <= curmin; i ++)    
               list[listlen++] = i;   
            qsort(list, listlen, sizeof(list[0]), listcmp);   
            for (i = 0; i < listlen; i ++)    
               for (j = i + 1; j < listlen && point[list[j]].y - point[list[i]].y <= curmin; j ++)     
                curmin = getmin(curmin, dis(point[list[i]], point[list[j]]));   
            return curmin; 
            }

            int init(void)
            {
            int i;
            scanf("%d", &n);      
            for (i=0;i<n;i++) 
               scanf("%lf%lf",&point[i].x,&point[i].y);      
            qsort(point,n,sizeof(point[0]),sortcmp);
            return n;
            }


            自己寫的代碼:

            /*
             * Problem(classic):
             *    there're many points in a plane surface, find the nearest two points
             *    see: <CLRS> 33.4 section
             
            */
            #include
            <stdio.h>
            #include
            <stdlib.h>
            #include
            <string.h>
            #include
            <math.h>
            #define INF 0x7FFFFFFF
            #define NUM_MAX 100000
            #define THRESHOLD 3

            struct Point {
                
            double x, y;
            };
            struct Point points[NUM_MAX];
            int total, yindex[NUM_MAX];

            double
            min(
            double arg1, double arg2)
            {
                
            return (arg1 <= arg2 ? arg1 : arg2);
            }

            double
            distance(
            struct Point *arg1, struct Point *arg2)
            {
                
            double x_diff = arg1->- arg2->x;
                
            double y_diff = arg1->- arg2->y;
                
            return sqrt(x_diff*x_diff + y_diff*y_diff);
            }

            int
            compare_x(
            const void *arg1, const void *arg2)
            {
                
            struct Point *p1 = (struct Point *)arg1;
                
            struct Point *p2 = (struct Point *)arg2;
                
            return (p1->- p2->x);
            }

            int
            compare_y(
            const void *arg1, const void *arg2)
            {
                
            struct Point *p1 = points + *(int *)arg1;
                
            struct Point *p2 = points + *(int *)arg2;
                
            return (p1->- p2->y);
            }

            void
            init_preprocess()
            {
                
            int i;
                scanf(
            "%d"&total);
                
            for(i=0; i<total; ++i)
                    scanf(
            "%lf %lf"&points[i].x, &points[i].y);
                qsort(points, total, 
            sizeof(struct Point), compare_x);
            }

            double
            find_nearest(
            int begin, int end)
            {
                
            int i, j;
                
            double ret = INF;
                
            if(end-begin+1 <= THRESHOLD) {
                    
            for(i=begin; i<end; ++i) {
                        
            for(j=i+1; j<=end; ++j)
                            ret 
            = min(ret, distance(points+i, points+j));
                    }
                    
            return ret;
                }
                
            int mid = begin + ((end - begin) >> 1);
                
            double dis = min(find_nearest(begin, mid), find_nearest(mid+1, end));
                
            int len = 0;
                
            for(j=mid; j>=begin && points[mid+1].x-points[j].x<=dis; --j)
                    yindex[len
            ++= j;
                
            for(j=mid+1; j<=end && points[j].x-points[mid].x<=dis; ++j)
                    yindex[len
            ++= j;
                qsort(yindex, len, 
            sizeof(int), compare_y);
                ret 
            = dis;
                
            for(i=0; i<=len-7++i) {
                    
            for(j=i+1; j<=i+7++j)
                        ret 
            = min(ret, distance(points+yindex[i], points+yindex[j]));
                }
                
            return ret;
            }

            double
            brute_force(
            int begin, int end)
            {
                
            double ret = INF;
                
            int i, j;
                
            for(i=begin; i<end; ++i) {
                    
            for(j=i+1; j<=end; ++j)
                        ret 
            = min(ret, distance(points+i, points+j));
                }
                
            return ret;
            }

            int
            main(
            int argc, char **argv)
            {
                init_preprocess();
                
            double ret = find_nearest(0, total-1);
                printf(
            "\nNearest Distance[Brute Force]: %f\n", brute_force(0, total-1));
                printf(
            "\nNearest Distance: %f\n", ret);
            }


            posted on 2011-09-03 23:17 simplyzhao 閱讀(1154) 評論(1)  編輯 收藏 引用 所屬分類: R_找工復習2011

            評論

            # re: 2011分治-平面最近點對(附C++源代碼) 2011-11-05 11:45 co

            好東西啊,非常感謝!寫的很簡潔  回復  更多評論   

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            中文国产成人精品久久不卡| 亚洲精品无码久久毛片| 2021国内精品久久久久久影院| 日本道色综合久久影院| 亚洲欧洲久久久精品| 国产精品久久久久久久人人看| 中文国产成人精品久久不卡| 91精品国产91久久| 久久亚洲sm情趣捆绑调教| 久久无码专区国产精品发布| 韩国无遮挡三级久久| 久久精品国产第一区二区| 欧美噜噜久久久XXX| 久久人人爽人人澡人人高潮AV| 久久久久夜夜夜精品国产| 久久亚洲国产成人影院| 久久久WWW成人免费精品| 丰满少妇人妻久久久久久4| 久久国产免费直播| 欧美熟妇另类久久久久久不卡 | 无码任你躁久久久久久| 欧美久久综合性欧美| 久久国产精品77777| 亚洲午夜无码久久久久| 亚洲欧洲日产国码无码久久99| 91精品国产综合久久香蕉| 国产精品欧美亚洲韩国日本久久| 色欲久久久天天天综合网精品 | 国产精品久久99| 久久超碰97人人做人人爱| segui久久国产精品| 99久久综合国产精品二区| 少妇熟女久久综合网色欲| 浪潮AV色综合久久天堂| 久久香综合精品久久伊人| 久久99国产精品99久久| 久久久精品人妻无码专区不卡| 日韩欧美亚洲国产精品字幕久久久| 亚洲香蕉网久久综合影视| 久久九九亚洲精品| 亚洲va久久久噜噜噜久久|