简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)

 

题目传送门

题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积。

分析:这是个阿波罗尼斯圆。既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y + E/2) ^ 2 = (D ^ 2 + E ^ 2 - 4 * F)  / 4,通过PB == PA * k解方程来求解圆心以及半径。然后就是套模板啦,上海交大的红书。

 

#include <bits/stdc++.h>
using namespace std;
 
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 5e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);

int dcmp(double x)  {
    if (fabs (x) < EPS)   return 0;
    else    return x < 0 ? -1 : 1;
}
struct Point    {
    double x, y;
    Point ()    {}
    Point (double x, double y) : x (x), y (y) {}
    Point operator + (const Point &r) const {       //向量加法
        return Point (x + r.x, y + r.y);
    }
    Point operator - (const Point &r) const {
        return Point (x - r.x, y - r.y);
    }
    Point operator * (double p) const {       //向量乘以标量
        return Point (x * p, y * p);
    }
    Point operator / (double p) const {       //向量除以标量
        return Point (x / p, y / p);
    }
    bool operator < (const Point &r) const  {
        return x < r.x || (x == r.x && y < r.y);
    }
    bool operator == (const Point &r) const {
        return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
    }
};
typedef Point Vector;
Point read_point(void)  {
    double x, y;    scanf ("%lf%lf", &x, &y);
    return Point (x, y);
}
double polar_angle(Vector V)    {
    return atan2 (V.y, V.x);
}
double dot(Point a, Point b)    {
    return a.x * b.x + a.y * b.y;
}
double cross(Point a, Point b)  {
    return a.x * b.y - a.y * b.x;
}
double length(Vector V) {
    return sqrt (dot (V, V));
}
double my_sqrt(double x)    {
    return sqrt (max (0.0, x));
}
 
Point ps[N];
double r, k;
double x1, _y1, x2, _y2;
int n;
 
double sqr(double x)    {
    return x * x;
}
 
struct  Line    {
    Point p;
    Vector v;
    double r;
    Line () {}
    Line (const Point &p, const Vector &v) : p (p), v (v) {
        r = polar_angle (v);
    }
    Point point(double a)   {
        return p + v * a;
    }
};
 
struct Circle   {
    Point c;
    double r;
    Circle () {}
    Circle (Point c, double r) : c (c), r (r) {}
    Point point(double a)   {
        return Point (c.x + cos (a) * r, c.y + sin (a) * r);
    }
};
 
int line_cir_inter(Line L, Circle C, double &t1, double &t2, vector<Point> &P)    {
    double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
    double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
    double delta = f * f - 4 * e * g;
    if (dcmp (delta) < 0)   return 0;
    if (dcmp (delta) == 0)  {
        t1 = t2 = -f / (2 * e); P.push_back (L.point (t1));
        return 1;
    }
    t1 = (-f - sqrt (delta)) / (2 * e);
    t2 = (-f + sqrt (delta)) / (2 * e);
    if (t1 > t2)    swap (t1, t2);
    if (dcmp (t1) > 0 && dcmp (t1 - 1) < 0) P.push_back (L.point (t1));
    if (dcmp (t2) > 0 && dcmp (t2 - 1) < 0) P.push_back (L.point (t2));
    return (int) P.size ();
}
 
double sector_area(Point a, Point b)    {
    double theta = polar_angle (a) - polar_angle (b);
    while (dcmp (theta) <= 0)   theta += 2 * PI;
    while (theta > 2 * PI)  theta -= 2 * PI;
    theta = min (theta, 2 * PI - theta);
    return r * r * theta / 2;
}
 
double cal(Point a, Point b)    {
    double t1, t2;
    bool ina = dcmp (length (a) - r) < 0;
    bool inb = dcmp (length (b) - r) < 0;
    if (ina && inb) return fabs (cross (a, b)) / 2.0;
    vector<Point> p;
    int num = line_cir_inter (Line (a, b - a), Circle (Point (0, 0), r), t1, t2, p);
    if (ina)    return sector_area (b, p[0]) + fabs (cross (a, p[0])) / 2.0;
    if (inb)    return sector_area (p[0], a) + fabs (cross (p[0], b)) / 2.0;
    if (num == 2)   return sector_area (a, p[0]) + sector_area (p[1], b) + fabs (cross (p[0], p[1])) / 2.0;
    return sector_area (a, b);
}
 
double cir_poly_area()  {
    double ret = 0;
    for (int i=0; i<n; ++i) {
        int sgn = dcmp (cross (ps[i], ps[i+1]));
        if (sgn != 0)   {
            ret += sgn * cal (ps[i], ps[i+1]);
        }
    }
    return ret;
}
 
void init(void) {
    double D = (2 * x2 - 2 * sqr (k) * x1) / (1 - sqr (k));
    double E = (2 * _y2 - 2 * sqr (k) * _y1) / (1 - sqr (k));
    double F = (sqr (k*x1)+sqr (k*_y1)-sqr (x2)-sqr(_y2)) / (1 - sqr (k));
    double x0 = D / 2, y0 = E / 2;
    r = sqrt (F + sqr (D)/4 + sqr (E)/4);
    for (int i=0; i<n; ++i) {
        ps[i].x -= x0;  ps[i].y -= y0;
    }
    ps[n] = ps[0];
}
 
int main(void)    {
    int cas = 0;
    while (scanf ("%d%lf", &n, &k) == 2)    {
        for (int i=0; i<n; ++i) {
            ps[i] = read_point ();
        }
        scanf ("%lf%lf", &x1, &_y1);
        scanf ("%lf%lf", &x2, &_y2);
        init ();
        printf ("Case %d: %.10f\n", ++cas, fabs (cir_poly_area ()));
    }
 
   //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
 
    return 0;
}

 

  

 

转载于:https://www.cnblogs.com/Running-Time/p/4949990.html

技术选型 【后端】:Java 【框架】:springboot 【前端】:vue 【JDK版本】:JDK1.8 【服务器】:tomcat7+ 【数据库】:mysql 5.7+ 项目包含前后台完整源码。 项目都经过严格调试,确保可以运行! 具体项目介绍可查看博主文章或私聊获取 助力学习实践,提升编程技能,快来获取这份宝贵的资源吧! 在当今快速发展的信息技术领域,技术选型是决定一个项目成功与否的重要因素之一。基于以下的技术栈,我们为您带来了一份完善且经过实践验证的项目资源,让您在学习和提升编程技能的道路上事半功倍。以下是该项目的技术选型和其组件的详细介绍。 在后端技术方面,我们选择了Java作为编程语言。Java以其稳健性、跨平台性和丰富的库支持,在企业级应用中处于领导地位。项目采用了流行的Spring Boot框架,这个框架以简化Java企业级开发而闻名。Spring Boot提供了简洁的配置方式、内置的嵌入式服务器支持以及强大的生态系统,使开发者能够更高效地构建和部署应用。 前端技术方面,我们使用了Vue.js,这是一个用于构建用户界面的渐进式JavaScript框架。Vue以其易上手、灵活和性能出色而受到开发者的青睐,它的组件化开发思想也有助于提高代码的复用性和可维护性。 项目的编译和运行环境选择了JDK 1.8。尽管Java已经推出了更新的版本,但JDK 1.8依旧是一种成熟且稳定的选择,广泛应用于各类项目中,确保了兼容性和稳定性。 在服务器方面,本项目部署在Tomcat 7+之上。Tomcat是Apache软件基金会下的一个开源Servlet容器,也是应用最为广泛的Java Web服务器之一。其稳定性和可靠的性能表现为Java Web应用提供了坚实的支持。 数据库方面,我们采用了MySQL 5.7+。MySQL是一种高效、可靠且使用广泛的关系型数据库管理系统,5.7版本在性能和功能上都有显著的提升。 值得一提的是,该项目包含了前后台的完整源码,并经过严格调试,确保可以顺利运行。通过项目的学习和实践,您将能更好地掌握从后端到前端的完整开发流程,提升自己的编程技能。欢迎参考博主的详细文章或私信获取更多信息,利用这一宝贵资源来推进您的技术成长之路!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值