この問題を O(n) 時間で解決する簡単な方法は、inversion in a circleを使用することです。
概要
セットから任意の点 O(x,y) を選択して原点とr
し、選択した点を中心とする半径の円を選択します。点 O が原点になるように、すべての点が (-x,-y) だけ平行移動すると、計算が簡単になります。
原点と円を選択したら、選択した円に関してセット内の他のすべての点に対して反転操作を実行します。座標では、点 P(x,y) を座標 の新しい点 P' にマップします(x',y') = (x,y)*r^2/(x^2+y^2)
。原点 O(0,0) は無限遠点に向かいます。
逆変換を使用すると、問題は必要なプロパティを持つ線を見つけることになります (線は常に無限遠点を通過するため、2 つの変換された点を通過します。さらに、線は残りの変換された点を 2 つの等しいセットに分割する必要があります)。
反転は、3 つの共線ポイントと 4 つの同心ポイントのセットを 3 つの共線ポイントと 4 つの同心ポイントのセットにマッピングすることに注意してください。したがって、変換されたセットには、3 つの共線ポイントと 4 つの同心ポイントはありません。
円を構築するために、逆反転を実行します (円の反転はインボリューション、つまり自己逆変換であるため、元の反転と同じです)。これにより、元のセットから最初に選択された点と他の 2 つの点を通る円に線が引き戻されます。残りの半分は円の内側にあり、半分は外側にあります。
対応する線の問題
ここで、問題を次のように縮小しました: 平面内に 2n+2 点が与えられた場合、残りの 2n 点のうち、n が線の片側にあり、n が反対側にあるような 2 つの点を通る線を見つけます。 .
その質問に O(n) 時間で次のように答えることができます。まず、セットの凸包の境界に 1 つの点が必要です (凸包全体は必要ありません)。このような点 P は、座標の最小 x 値を持つセット内の点を見つけることで見つけることができます。これは、Quickselect アルゴリズムを使用して O(n) 時間で実行できます。
これで、すべてのポイントが P の右側の半空間にあることがわかりました。次のステップのアイデアは、P を通る水平線 h に対するすべてのポイントの中央角でポイント Q を見つけることです。 Quickselect アルゴリズムを使用すると、O(n) 時間で実行できます。同一線上にある 3 つの点はあり得ないので、同じ角度の 2 つの点はあり得ません。
直線 PQ は 2 つの点を通過し、角度 Rph が QPh より大きいか QPh より小さいか (負の角度は h より小さい) に従って、残りの点 R を 2 つの等しい部分に分割します。
小さな問題が 1 つ発生する可能性があります。線分が原点を通過する場合、反転により円ではなく別の線分になります。ただし、元のセットに 3 つの同一線上の点があり、問題ステートメントによってそうではないことが保証されていることを意味するため、そのような状況は発生しません。