給定平面上n個點的座標,找出距離最近的兩個點。
根據水平方向的座標把平面上的n個點分成兩部分left和right。假設分別求出了left和right兩部分中距離最近的點對之最短距離mindist(left)和mindist(right),還有一種情況沒有考慮,那就是點對中乙個點來自於left部分,另乙個點來自right部分。最直接的想法,那就是窮舉left和right兩個部分之間的點對,這樣的點對很多,最多可能有n*n/4對。是否可以只考慮有可能成為最近點對的候選點呢?由於我們已經知道left和right兩個部分中的最近點對距離分別為mindist(left)和mindist(right),如果left和right之間的點對距離超過mdist=min(mindist(left),mindist(right)),我們則不會對他們感興趣,因為這些點對不可能是最近點對。
通過直線x=m將所有的點對分成xm兩部分(按照橫座標劃分),只要考慮x=m-mdist到x=m+mdist之間的這個帶狀區域內的最小點對,然後再更mdist比較就可以了。在計算帶狀區域的最小點對時,可以按y座標,對帶狀區域內的頂點進行排序,如果乙個點對的距離小於mdist,那麼他們一定在乙個mdist*(2*mdist)的矩形區域內。乙個mdist*(2*mdist)的區域內最多有8個點,對於任意乙個帶狀區域內的頂點,只要考察它與按照y座標排序且緊接著的7個點之間的距離就可以了。根據這個特點,我們可以用o(n)時間完成帶狀區域最近點對的查詢。
以下**:簡化了查詢過程,逐一計算帶狀區域內點對的距離。
#include
#include
#include
#include
class point
point() : x_(0), y_(0) {}
static bool orderbyx(const point& left, const point& right)
static bool orderbyy(const point& left, const point& right)
int x_;
int y_;
};float distance(const point& left, const point& right)
int nearestpoints(const std::vector& points, int start, int end, point* point1, point* point2)
}sort(left_part_points.begin(), left_part_points.end(), point::orderbyy);
std::vectorright_part_points;
for (int i = middle + 1; i <= end; ++i)
}sort(right_part_points.begin(), right_part_points.end(), point::orderbyy);
int distance_y = 0;
int point_distance = 0;
for (int i = 0; i < left_part_points.size(); ++i) }}
}return min_distance;
}else
}int main(int argc, char** argv)
尋找最近點對
一維的數很簡單,先排序,再掃瞄已排好的數,相鄰兩個進行比較即可,時間複雜度為o n log2n n o n log2n 兩維的話 把平面上n個點分成兩部分left和right。假設分別求出left和right兩部分最短距離mindistleft和mindistright,還有一種情況就是點對中乙個點...
尋找最近點對
問題 在空間中有n個點,尋找空間中最近的2個點。法一 遍歷,o n 2 法二 分治演算法 將點分為左右兩半,分別找到最近的2個點,然後考慮交叉位置的點對中的最小距離,在這3者中取最小的那個。o nlogn 步驟 1.按照x軸排序 2.找到中間點,分別進行處理 3.2邊處理完成,將進行 merge 過...
尋找最近點對
演算法導論上乙個經典演算法,講解可看 ac 的複雜度為 n lgn lgn,演算法導論上講還可以通過 預排序 不用每次都按照y排序,複雜度可下降為n lgn。上可以ac。include include include using namespace std define max 100005 def...