目次

同一直線上に並ぶ点のカウント

問題設定

制約とか

解法例

$O(N^3)$ 解法

(1)

全ての3点組について、同一直線上に存在するか調べればよい。

(2)

2点 $i,j$($i \lt j$)を固定し、通る直線 $L$ を求める。
3点目を $j \lt k$ の範囲で探索し、$L$ 上にあった $k$ の個数+2が、その直線が通る点の個数。

全ての $i,j$ を通して、最も通った点の数が多い直線が求めるもの。

3点が同一直線上か調べる方法

いくつかの方法がある。なるべく途中で小数が出てこないようにする方がよい。

面積が0

3点に囲まれた三角形の面積は以下で求められる。

これが0なら同一直線上にある。

反時計回り判定

幾何でよく使われるユーティリティ関数に、ccw(Counter-ClockWise、反時計回り判定)がある。
$A→B$ の線分から見て、$B→C$ がどっち向きに曲がっているか(まっすぐか)を、外積で判定する。

汎用性があるので、これで判定してもよい。

$O(N^2)$ 解法

2点組ごとに「2点を結ぶ直線の方程式 $ax+by+c=0$ の係数 $(a,b,c)$」を求め、それごとにカウントする。

$(x_1,y_1),(x_2,y_2)$ を通る直線の方程式は、$d_x=x_2-x_1,d_y=y_2-y_1$ として、以下のようになる。

ただし、係数に定数倍をかけたものは $(a,b,c)$ が異なっても同一の直線を示すので、それらを統一する必要がある。

こうすると、違いを吸収して、同一の直線は同一の $(a,b,c)$ となる。

$k$ 個の点が並ぶ直線は、$\dfrac{k(k-1)}{2}$ 回カウントされることになるので、 最終カウント結果から、各直線にいくつの点が並ぶか復元できる。

(1)

$O(N^2)$ 本の全てのカウントされた直線に対して個数を復元する。$k$ 個の点が並ぶ直線上には、${}_kC_{3}$ 組の3つ組みがある。

(2)

最も多くカウントされた直線が、求める直線である。