タイトルの説明
、二次元平面上の所定のn個の点が、その中に2点の距離の最も近い半分を見つけます。
入力データを、各試験の複数のセットを含むN、ポイントの数であり、次のn行、各行点座標。
場合n個の入力端を示し、距離の最も近い2点の半分のようなデータの各セットの出力線はゼロです。
サンプル入力:
2
0 0
1 1
2
1 1
1 1。
3。
-1.5 0
0 0
0 1.5
0
出力サンプル:
0.71
0.00
0.75
タイトル分析:
パーティションの考えを用いて、並び順のN点にx座標中間座標は、左右二つの部分に囲まれた
右別々し、次いで合わせた最も近い点のシーク距離の2つの部分を残しました。二つの部分の最も近い距離dのために決定され、
統合プロセスは、ほとんどのストリップ幅部2dは二組に属する2つのポイントがあり、距離がdよりも小さいか否かを確認する必要があり
、おそらくn点があり、最悪の場合時間が合併しましたO(N ^ 2)である。しかし、疎な性質を持つ点の左右には、下
左の任意の点について、点の右側は、矩形のD * 2dと、検査及びせいぜい6内に入らなければなりません点(
原則分類整理)ストリップ部の最初のポイントを組み合わせたときに、座標、及びリニアスキャンYに従ってソートされるように、
O(nlogn)の複雑さの間。
コード:
#include <iostreamの> する#include <stdio.hに> する#include <アルゴリズム> の#include <cmath> 使用して 名前空間STD。 ダブル MAX = 1E9; int型、B; 構造体ノード{ ダブルX、Y。 int型のキー; }。 [ARノード1000005 ]、BR [ 1000005 ]。 ブールcmpx(ノードA、ノードB){ 戻り AX < BX。 } ブールcmpy(ノードA、ノードB){ 戻り AY < によって、 } 二重DIS(ノードA、ノードB){ 戻り SQRT(POW(AX-BX、2)+ POW(AY-によって、2 ))。 } ダブル分(ダブル、ダブルB){ 戻り <bは?A:B; } 二重 CAL(INT S、INT E){ もし、(S == e)に 戻りMAXと、 int型の半ば。 半ば =(S + E)/ 2 。 ダブルD; D =分(CAL(S、MID)、CAL(MID + 1 、e)参照)。 int型 CNT = 0 ; ために(int型 I =中間と、I> = S && AR [中間] .X-AR [i]は.X <D; i-- ){ BR [CNT ++] = AR [i]は、 } のための(int型 I =中間+ 1 ; iは<= E && AR [I] .X-AR [中間] .X <D、iは++ ){ BR [CNT ++] =のAR [i]は、 } ソート(BR、BR + CNT、cmpy)。 以下のために(int型 i = 0 ; iは、CNT <; iは++ ){ ための(int型 J = iは+ 1、J <CNT; J ++ ){ 場合(D> DIS(BR [i]は、BR [J])) D =DIS(BR [i]は、BR [J])。 } } 戻りD。 } int型のmain(){ int型N; 一方、(CIN >> N && N){ ため(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %のLFの%のLF "、&AR [I] .X、&AR [I] .Y)。 AR [i]は.KEY = I。 } ソート(AR + 1は、Ar + N + 1 、cmpx)。 ダブル D = CAL(1 、N) printf(" %.2lfの\ nを「 D / 2.0 ); } 戻り 0 ; }
アイデア:
それぞれ半分ずつ、にx軸によると、考えられているパーティションを使用して、その後、2点分の間の最短距離を見つけることが、注意:それぞれ両側のビット、及び最小距離があるかもしれないので、我々は、セクションの最小を分離します全体決定するために、比較のための値を求めてこれにより位置の比較的小さなセクションに、二次元の空間との間の最小距離をので、我々はタイムアウトしないループのための2つを使用します。