Official

B - Two Rings Editorial by Nyaan


\(2\) 円の中心間距離を \(D\) とします。この時、\(2\) 円が共有点を持つ条件は

\[|R_1 - R_2| \leq D \leq R_1 + R_2\]

となります。参考:2つの円の位置関係(高校数学の美しい物語)

\(D = \sqrt{(X_1 - X_2)^2 + (Y_1 - Y_2)^2}\) なので

\[|R_1 - R_2| \leq \sqrt{(X_1 - X_2)^2 + (Y_1 - Y_2)^2} \leq R_1 + R_2\]

という式の真偽を評価すればこの問題を解くことが出来ます。しかし、上式を実際に計算すると誤差の影響で誤って答えが出る可能性があります。そこで、各項は非負であり両辺を 2 乗しても真偽が変化しないことを利用して、各辺を 2 乗した

\[(R_1 - R_2)^2 \leq (X_1 - X_2)^2 + (Y_1 - Y_2)^2 \leq (R_1 + R_2)^2\]

という式を評価すれば整数のみを利用して誤差なく式を評価できます。
計算量は \(\mathrm{O}(1)\) で十分高速です。

  • 実装例 (C++)
#include <iostream>
using namespace std;

int main() {
  int T;
  cin >> T;
  while (T--) {
    long long x1, y1, r1, x2, y2, r2;
    cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
    auto sq = [](long long x) { return x * x; };
    auto L = sq(r1 - r2);
    auto M = sq(x1 - x2) + sq(y1 - y2);
    auto R = sq(r1 + r2);
    cout << (L <= M and M <= R ? "Yes" : "No") << "\n";
  }
}

posted:
last update: