第一个AC
2025-08-09 11:19:55
发布于:北京
2阅读
0回复
0点赞
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
// 点结构
struct Point {
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
// 计算两点之间的距离
double distance(const Point& a, const Point& b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
// 计算点到线段的距离
double pointToSegmentDistance(const Point& p, const Point& a, const Point& b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
if (dx == 0 && dy == 0) { // a和b是同一点
return distance(p, a);
}
// 计算投影比例
double t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy);
t = max(0.0, min(1.0, t)); // 限制在[0,1]范围内
// 计算投影点
Point proj(a.x + t * dx, a.y + t * dy);
return distance(p, proj);
}
// 旋转点
Point rotatePoint(const Point& p, double angle) {
double rad = angle * M_PI / 180.0;
double cosA = cos(rad);
double sinA = sin(rad);
return Point(p.x * cosA + p.y * sinA, -p.x * sinA + p.y * cosA);
}
// 缩放点(将椭圆问题转化为圆问题)
Point scalePoint(const Point& p, double p_factor) {
return Point(p.x / p_factor, p.y);
}
// 寻找最小覆盖圆的中心和半径
pair<Point, double> findMinEnclosingCircle(const vector<Point>& points) {
int n = points.size();
if (n == 0) return {Point(), 0.0};
if (n == 1) return {points[0], 0.0};
// 初始圆心为前两点的中点,半径为两点距离的一半
Point center((points[0].x + points[1].x) / 2, (points[0].y + points[1].y) / 2);
double radius = distance(points[0], points[1]) / 2;
// 检查所有点是否在圆内
for (int i = 2; i < n; ++i) {
double d = distance(points[i], center);
if (d <= radius + 1e-8) continue; // 已在圆内
// 以当前点和第一个点为直径
center = Point((points[i].x + points[0].x) / 2, (points[i].y + points[0].y) / 2);
radius = distance(points[i], points[0]) / 2;
// 检查中间的点
for (int j = 1; j < i; ++j) {
d = distance(points[j], center);
if (d <= radius + 1e-8) continue;
// 以当前点和j点为直径
center = Point((points[i].x + points[j].x) / 2, (points[i].y + points[j].y) / 2);
radius = distance(points[i], points[j]) / 2;
// 检查之前的点
for (int k = 0; k < j; ++k) {
d = distance(points[k], center);
if (d <= radius + 1e-8) continue;
// 求三点的外接圆
const Point& A = points[i];
const Point& B = points[j];
const Point& C = points[k];
double d1 = 2 * (A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y));
if (fabs(d1) < 1e-8) { // 三点共线
// 找到最远的两个点
double distAB = distance(A, B);
double distAC = distance(A, C);
double distBC = distance(B, C);
if (distAB >= distAC && distAB >= distBC) {
center = Point((A.x + B.x) / 2, (A.y + B.y) / 2);
radius = distAB / 2;
} else if (distAC >= distAB && distAC >= distBC) {
center = Point((A.x + C.x) / 2, (A.y + C.y) / 2);
radius = distAC / 2;
} else {
center = Point((B.x + C.x) / 2, (B.y + C.y) / 2);
radius = distBC / 2;
}
} else {
double x1 = A.x * A.x + A.y * A.y;
double y1 = B.x * B.x + B.y * B.y;
double z1 = C.x * C.x + C.y * C.y;
double cx = (x1 * (B.y - C.y) + y1 * (C.y - A.y) + z1 * (A.y - B.y)) / d1;
double cy = (x1 * (C.x - B.x) + y1 * (A.x - C.x) + z1 * (B.x - A.x)) / d1;
center = Point(cx, cy);
radius = distance(center, A);
}
}
}
}
return {center, radius};
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<Point> originalPoints(n);
for (int i = 0; i < n; ++i) {
cin >> originalPoints[i].x >> originalPoints[i].y;
}
int a, p;
cin >> a >> p;
// 转换所有点:先旋转,再缩放
vector<Point> transformedPoints(n);
for (int i = 0; i < n; ++i) {
Point rotated = rotatePoint(originalPoints[i], a);
transformedPoints[i] = scalePoint(rotated, p);
}
// 找到最小覆盖圆
auto [center, radius] = findMinEnclosingCircle(transformedPoints);
// 输出结果,保留三位小数
cout << fixed << setprecision(3) << radius << endl;
return 0;
}
我是2025年8/9日11:19做的这道题,没有人做过,我是第一个
这里空空如也
有帮助,赞一个