• <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>

            poj 3714 Raid and hdu 1007 Quoit Design

               典型的最近點對算法的應用,不過這個題多了個限制條件,就是點分為2類,最短距離必須在不同的類之間。為了滿足這個限制,只需要
            把同類別點直接的距離都當作INF處理即可。
               最近點對的算法,算導上面說是nlogn的。但是這個復雜度實現起來略微麻煩點,有一種實現方法是n*logn*logn的,其只對x坐標進行
            了排序。n*logn的算法需要對x和y分量分別進行排序,還需要用到其它的輔助數組。
               第一個題我用了n*logn算法實現了,第二個題則用了n*logn*logn算法實現了。但是時間上相差不大,因為第一個算法每次進行分治時
            候消耗的O(n)時間也有幾次。第二個算法分治時候,需要再次排序的時間也不一定很多,因為可能數據量不夠大。
               算法的本質就是二分按照X排序好的點數組,n*logn*logn變成n*logn的關鍵是預先對y也排序好一個點數組,因為按y排序好的點數組,
            在分治后的合并中要用到。算法更詳細的解釋請參照算法導論。

            poj 3714 代碼如下: 

            #include <stdio.h>
            #include <string.h>
            #include <math.h>
            #include <algorithm>
            using namespace std;
            #define MAX_N (100000 * 2 + 10)
            const double FINF = 1LL << 60;
            struct Point
            {
                double x, y;
                int nKind;
            };
            Point pts[MAX_N], ptsY[MAX_N], ptsTemp[MAX_N];
            Point ptsSave[MAX_N];
            int nNum;
            bool CmpX(const Point& a, const Point& b)
            {
                return a.x < b.x;
            }

            bool CmpY(const Point& a, const Point& b)
            {
                return a.y < b.y;
            }

            double Dis(Point a, Point b)
            {
                if (a.nKind == b.nKind)
                {
                    return FINF;
                }
                else
                {
                    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
                }
            }

            double FindMinDis(Point pts[], Point ptsY[], Point ptsTemp[], int nBeg, int nEnd)
            {
                if (nBeg == nEnd)
                {
                    return FINF;
                }
                else if (nBeg + 1 == nEnd)
                {
                    return Dis(pts[nBeg], pts[nEnd]);
                }
                else if (nBeg + 2 == nEnd)
                {
                    return min(min(Dis(pts[nBeg], pts[nBeg + 1]), Dis(pts[nBeg], pts[nEnd])),
                               Dis(pts[nBeg + 1], pts[nEnd]));
                }
                else
                {
                    memcpy(ptsSave + nBeg, ptsY + nBeg, sizeof(Point) * (nEnd - nBeg + 1));//保存當前的Y坐標順序
                    int nMid = (nBeg + nEnd) / 2;
                    int nL = nBeg;
                    int nR = nMid + 1;
                    for (int i = nBeg; i <= nEnd; ++i)
                    {
                        if (ptsY[i].x - pts[nMid].x <= 0)
                        {
                            ptsTemp[nL++] = ptsY[i];
                        }
                        else
                        {
                            ptsTemp[nR++] = ptsY[i];
                        }
                    }
                    
                    double fAns = min(FindMinDis(pts, ptsTemp, ptsY, nBeg, nMid),
                                      FindMinDis(pts, ptsTemp, ptsY, nMid + 1, nEnd));
                    int nK = 1;
                    
                    for (int i = nBeg; i <= nEnd; ++i)
                    {
                        if (fabs(ptsSave[i].x - pts[nMid].x) <= fAns)
                        {
                            ptsTemp[nK++] = ptsSave[i];
                        }
                    }
                    for (int i = 1; i < nK; ++i)
                    {
                        for (int j = i + 1; j < nK; ++j)
                        {
                            if (ptsTemp[j].y - ptsTemp[i].y > fAns)
                            {
                                break;
                            }
                            fAns = min(fAns, Dis(ptsTemp[i], ptsTemp[j]));
                        }
                    }
                    return fAns;
                }
            }

            int main()
            {
                int nT;
                int nN;
                
                //printf("%f", FINF);
                scanf("%d", &nT);
                while (nT--)
                {
                    scanf("%d", &nN);
                    nNum = nN * 2;
                    for (int i = 0; i < nN; ++i)
                    {
                        scanf("%lf%lf", &pts[i].x, &pts[i].y);
                        pts[i].nKind = 1;
                    }
                    for (int i = nN; i < nNum; ++i)
                    {
                        scanf("%lf%lf", &pts[i].x, &pts[i].y);
                        pts[i].nKind = 2;
                    }
                    memcpy(ptsY, pts, sizeof(Point) * nNum);
                    sort(pts, pts + nNum, CmpX);
                    sort(ptsY, ptsY + nNum, CmpY);
                    printf("%.3f\n", FindMinDis(pts, ptsY, ptsTemp, 0, nNum - 1));
                }
                
                return 0;
            }

            hdu 1007 代碼如下:
            #include <stdio.h>
            #include <math.h>
            #include <algorithm>
            using namespace std;
            #define MAX (100000 + 10)
            struct Point
            {
                double x, y;
            };
            Point pts[MAX];
            Point ptsTemp[MAX];
            const double FINF = 1LL << 60;
            bool CmpX(const Point& a, const Point& b)
            {
                return a.x < b.x;
            }

            bool CmpY(const Point& a, const Point& b)
            {
                return a.y < b.y;
            }

            double Dis(Point a, Point b)
            {
                return sqrt((a.x - b.x) * (a.x - b.x) + (b.y - a.y) * (b.y - a.y));
            }

            double Find(int nL, int nH)
            {
                if (nL == nH)
                {
                    return FINF;
                }
                else if (nL + 1 == nH)
                {
                    return Dis(pts[nL], pts[nH]);
                }
                else if (nL + 2 == nH)
                {
                    return min(Dis(pts[nL], pts[nL + 1]), 
                               min(Dis(pts[nL], pts[nH]), Dis(pts[nH], pts[nL + 1])));
                }
                else
                {
                    int nMid = (nL + nH) / 2;
                    double fAns = min(Find(nL, nMid), Find(nMid + 1, nH));
                    int nK = 0;
                    for (int i = nL; i <= nH; ++i)
                    {
                        if (fabs(pts[i].x - pts[nMid].x) <= fAns)
                        {
                            ptsTemp[nK++] = pts[i];
                        }
                    }
                    sort(ptsTemp, ptsTemp + nK, CmpY);
                    for (int i = 0; i < nK; ++i)
                    {
                        for (int j = i + 1; j < nK; ++j)
                        {
                            if (ptsTemp[j].y - ptsTemp[i].y >= fAns)
                            {
                                break;
                            }
                            fAns = min(fAns, Dis(ptsTemp[j], ptsTemp[i]));
                        }
                    }
                    
                    return fAns;
                }
            }

            int main()
            {
                int nN;
                
                while (scanf("%d", &nN), nN)
                {
                    for (int i = 0; i < nN; ++i)
                    {
                        scanf("%lf%lf", &pts[i].x, &pts[i].y);
                    }
                    sort(pts, pts + nN, CmpX);
                    printf("%.2f\n", Find(0, nN -1) * 0.5);
                }
                
                return 0;
            }

            posted on 2012-07-18 13:53 yx 閱讀(1164) 評論(0)  編輯 收藏 引用 所屬分類: 計算幾何

            <2012年7月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久亚洲AV无码观看| 亚洲另类欧美综合久久图片区| 久久e热在这里只有国产中文精品99| 亚洲级αV无码毛片久久精品| 伊人色综合久久天天网| 色欲综合久久躁天天躁| 久久久久国色AV免费观看| 久久人人爽人人爽人人片AV麻豆| 国产精品99久久久久久www| 欧美777精品久久久久网| 99久久国产热无码精品免费久久久久| 老色鬼久久亚洲AV综合| 72种姿势欧美久久久久大黄蕉| av无码久久久久久不卡网站| 久久国产精品99久久久久久老狼| 精品国产一区二区三区久久久狼| 精品久久777| 久久青青草原精品国产不卡| 国产香蕉久久精品综合网| 久久精品国产AV一区二区三区| 亚洲AV日韩AV永久无码久久 | 精品久久一区二区| 伊人丁香狠狠色综合久久| 欧美精品丝袜久久久中文字幕 | 亚洲AV日韩AV天堂久久| 久久狠狠高潮亚洲精品| 曰曰摸天天摸人人看久久久| 亚洲国产小视频精品久久久三级 | 久久精品一区二区国产| 久久99精品久久久久久不卡| 亚洲午夜福利精品久久 | 99久久国产热无码精品免费| 国产精品欧美久久久久无广告 | 九九久久99综合一区二区| 免费一级欧美大片久久网| 亚洲中文字幕无码久久综合网| 久久久精品午夜免费不卡| 一极黄色视频久久网站| 成人精品一区二区久久久| av色综合久久天堂av色综合在| 国产69精品久久久久9999|