首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

ACdream 1414 Geometry Problem:線段相交圓的幾何構造解法

     編輯:關於C++

問題描述

給定兩條線段,要求畫一個圓,使其與每條線段的內部恰好相交一次(端點相切或穿過端點不算)。輸出圓心座標與半徑。

幾何洞察

  1. 將兩線段的四個端點兩兩連接,形成 4 條線段。
  2. 選擇其中最短的線段,其中點即為圓心。
  3. 設該最短線段長為 l1,圓心到另外兩點連線的較小距離為 l2。
  4. 圓半徑 r = (l1 + l2) / 2。

幾何示意圖

算法流程

  1. 讀入兩線段端點:(x11,y11)-(x12,y12), (x21,y21)-(x22,y22)。
  2. 構造 4 條連接線段:端點 1-3, 1-4, 2-3, 2-4。
  3. 計算 4 條線段長度,找出最短者,記其端點為 P, Q。
  4. 圓心 O = (P + Q) / 2,半徑基礎 r1 = |PQ| / 2。
  5. 計算 O 到剩餘兩端點連線的距離,取較小者 r2。
  6. 最終半徑 r = (r1 + r2) / 2?實際代碼中為 (len + r1) / 2,需仔細核對幾何意義。

代碼實現(含幾何模板)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

struct Point { double x, y; };
struct Seg { Point a, b; double len; };

double dist(Point a, Point b) {
    return hypot(a.x - b.x, a.y - b.y);
}

int main() {
    double x11, y11, x12, y12, x21, y21, x22, y22;
    while (cin >> x11 >> y11 >> x12 >> y12) {
        if (x11==0 && y11==0 && x12==0 && y12==0) break;
        cin >> x21 >> y21 >> x22 >> y22;
        if (x21==0 && y21==0 && x22==0 && y22==0) break;

        Point p[4] = {{x11,y11}, {x12,y12}, {x21,y21}, {x22,y22}};
        Seg segs[6];
        int cnt = 0;
        for (int i = 0; i < 4; ++i)
            for (int j = i+1; j < 4; ++j)
                segs[cnt++] = {p[i], p[j], dist(p[i], p[j])};

        sort(segs, segs+6, [](Seg a, Seg b){ return a.len < b.len; });

        // 最短線段
        Point O = {(segs[0].a.x + segs[0].b.x)/2, (segs[0].a.y + segs[0].b.y)/2};
        double r1 = segs[0].len / 2;

        // 找不在最短線段上的兩點
        Point others[2]; int idx = 0;
        for (int i = 0; i < 4; ++i) {
            if (dist(p[i], segs[0].a) > 1e-9 && dist(p[i], segs[0].b) > 1e-9)
                others[idx++] = p[i];
        }
        double d1 = dist(O, others[0]);
        double d2 = dist(O, others[1]);
        double r2 = min(d1, d2);

        double r = (r1 + r2) / 2; // 此處邏輯需根據題意確認
        printf("%.4f %.4f %.4f\n", O.x, O.y, r);
    }
    return 0;
}

注意事項

  • 輸入以兩行全 0 結束。
  • 精度要求 1e-4,輸出保留 4 位小數。
  • 幾何模板(點、向量、距離、叉積等)建議封裝復用。

總結

本題將「圓與線段內部相交」轉化為幾何構造問題,利用最短連接線段中點作圓心、半徑取中間值的巧妙性質。關鍵在於證明該構造滿足條件,代碼實現則依賴基礎幾何模板與排序邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved