列表

详情


NC20428. [SHOI2014]信号增幅仪

描述

无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站....
就在你拿起键盘准备开始敲代码的时候,你的好朋友发明家 SHTSC 突然出现了。SHTSC 刚刚完成了他的新发明——无线信号增幅仪。
增幅仪能够在不增加无线基 站功耗的前提下,使得有效信号的覆盖范围在某一特定方向上伸长若干倍。即:使用了增幅仪的无线基站覆盖范围是个椭圆,其功耗正比于半短轴长的平方。
现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站 ,并在增幅仪的帮助下使所有的用户都能接收到信号,且无线基站的功耗最小。注意:由于SHTSC 增幅仪的工作原理依赖地磁场,增幅的方向是恒定的。

输入描述

第一行一个整数:n。平面内的用户个数。
之后的n行每行两个整数x, y,表示一个用户的位置。
第n+2行一个整数:a。表示增幅仪的增幅方向,单位是度。表示增幅仪的方向是从x正方向逆时针转a度。
第 n+3行一个整数:p。表示增幅仪的放大倍数。

输出描述

输出一行一个实数,为能够覆盖所有用户的最小椭圆的半短轴长,四舍五入到三位小数。

示例1

输入:

2
1 0 
-1 0 
0 
2

输出:

0.500

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 78ms, 内存消耗: 1196K, 提交时间: 2022-06-21 21:59:45

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define x first
#define y second
typedef pair<double, double> PDD;
const int maxn = 50010;
const double eps = 1e-8;
const double pi = acos(-1);
typedef struct node
{
    PDD p;
    double r;
}Circle;
PDD q[maxn];
int n;
int sign(double x)
{
    if(fabs(x) < eps) return 0;
    if(x < 0) return -1;
    return 1;
}
int dcmp(double x, double y)
{
    if(fabs(x - y) < eps) return 0;
    if(x < y) return -1;
    return 1;
}
PDD operator + (PDD a, PDD b)
{
    return {a.x + b.x, a.y + b.y};
}
PDD operator - (PDD a, PDD b)
{
    return {a.x - b.x, a.y - b.y};
}
double operator * (PDD a, PDD b)
{
    return a.x * b.y - a.y * b.x;
}
PDD operator * (PDD a, double t)
{
    return {a.x * t, a.y * t};
}
PDD operator / (PDD a, double b)
{
    return {a.x / b, a.y / b};
}
double get_dist(PDD a, PDD b)
{
    double dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}
PDD get_line_intersection(PDD p, PDD v, PDD q, PDD w)
{
    auto u = p - q;
    double t = w * u / (v * w);
    return p + v * t;
}
PDD rotate(PDD a, double b)
{
    return {a.x * cos(b) + a.y * sin(b), -a.x * sin(b) + a.y * cos(b)};
}
pair<PDD, PDD> get_line(PDD a, PDD b)
{
    return {(a + b) / 2, rotate(b - a, pi / 2)};
}
Circle get_circle(PDD a, PDD b, PDD c)
{
    auto u = get_line(a, b), v = get_line(a, c);
    auto p = get_line_intersection(u.x, u.y, v.x, v.y);
    return {p, get_dist(p, a)};
}
int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++) cin >> q[i].x >> q[i].y;
    double theta, p; cin >> theta >> p;
    for(int i = 0; i < n; i ++){
        q[i] = rotate(q[i], theta / 180 * pi);
        q[i].x /= p;
    }
    random_shuffle(q, q + n);
    Circle c({q[0], 0});
    for(int i = 1; i < n; i ++){
        if(dcmp(c.r, get_dist(c.p, q[i])) < 0){
            c = {q[i], 0};
            for(int j = 0; j < i; j ++){
                if(dcmp(c.r, get_dist(c.p, q[j])) < 0){
                    c = {(q[i] + q[j]) / 2, get_dist(q[i], q[j]) / 2};
                    for(int k = 0; k < j; k ++){
                        if(dcmp(c.r, get_dist(c.p, q[k])) < 0){
                            c = get_circle(q[i], q[j], q[k]);
                        }
                    }
                }
            }
        }
    }
    printf("%.3lf\n", c.r);
    return 0;
}

上一题