結果
| 問題 |
No.3344 Common Tangent Line
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-21 19:58:07 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 701 ms / 3,000 ms |
| コード長 | 2,104 bytes |
| コンパイル時間 | 1,013 ms |
| コンパイル使用メモリ | 121,264 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-11-21 19:59:04 |
| 合計ジャッジ時間 | 26,320 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 40 |
ソースコード
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
// 直線 ax + by + c = 0 に対する評価値を計算する関数
double get_val(double a, double b, double c) {
double M = max({abs(a), abs(b), abs(c)});
if (M == 0) return 0; // 通常ありえないケース
return abs(a + b + c) / M;
}
void solve() {
double x1, y1, r1;
double x2, y2, r2;
// 入力の読み込み
if (!(cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2)) return;
// 中心間距離 D の計算
double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
double D = sqrt(distSq);
// 中心を結ぶベクトルの角度 beta
double beta = atan2(y2 - y1, x2 - x1);
double total_X = 0.0;
// --- 共通外接線 (2本) ---
// 条件: cos(theta - beta) = (r2 - r1) / D
// 制約より D > r1 + r2 なので、分母が0になることや範囲外になることはない
double phi_ext = acos((r2 - r1) / D);
double thetas_ext[2] = {beta + phi_ext, beta - phi_ext};
for (double theta : thetas_ext) {
double a = cos(theta);
double b = sin(theta);
// 円1の中心からの距離が r1 となるように c を決定
double c = r1 - (a * x1 + b * y1);
total_X += get_val(a, b, c);
}
// --- 共通内接線 (2本) ---
// 条件: cos(theta - beta) = -(r1 + r2) / D
double phi_int = acos(-(r1 + r2) / D);
double thetas_int[2] = {beta + phi_int, beta - phi_int};
for (double theta : thetas_int) {
double a = cos(theta);
double b = sin(theta);
// 外接線と同様の式で c を決定できる(幾何学的に整合する)
double c = r1 - (a * x1 + b * y1);
total_X += get_val(a, b, c);
}
// 結果の出力
cout << fixed << setprecision(16) << total_X << endl;
}
int main() {
// 高速化
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
if (cin >> t) {
while(t--) {
solve();
}
}
return 0;
}