• [hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长


    题意:如题

    思路:离散。将所有交点求出来,相当于将多变形的边切成了很多条元边,对每条元边,有两种情况

    • 在圆内,答案加上此边长
    • 在圆外,答案加上此边相对于圆心的"有向转弧"
    #include <bits/stdc++.h>
    using namespace std;
    #ifndef ONLINE_JUDGE
        #include "local.h"
    #endif
    #define X first
    #define Y second
    #define pb(x) push_back(x)
    #define mp(x, y) make_pair(x, y)
    #define all(a) (a).begin(), (a).end()
    #define mset(a, x) memset(a, x, sizeof(a))
    #define mcpy(a, b) memcpy(a, b, sizeof(a))
    typedef long long ll;
    template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
    template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
    
    
    namespace ConstSet {
        const double PI = acos(-1.0);
        const double e = 2.718281828459045;
    }
    
    const double eps = 1e-8;
    struct Real {
        double x;
        double get() { return x; }
        int read() { return scanf("%lf", &x); }
        Real(const double &x) { this->x = x; }
        Real() {}
        Real abs() { return x > 0? x : -x; }
    
        Real operator + (const Real &that) const { return Real(x + that.x);}
        Real operator - (const Real &that) const { return Real(x - that.x);}
        Real operator * (const Real &that) const { return Real(x * that.x);}
        Real operator / (const Real &that) const { return Real(x / that.x);}
        Real operator - () const { return Real(-x); }
    
        Real operator += (const Real &that) { return Real(x += that.x); }
        Real operator -= (const Real &that) { return Real(x -= that.x); }
        Real operator *= (const Real &that) { return Real(x *= that.x); }
        Real operator /= (const Real &that) { return Real(x /= that.x); }
    
        bool operator < (const Real &that) const { return x - that.x <= -eps; }
        bool operator > (const Real &that) const { return x - that.x >= eps; }
        bool operator == (const Real &that) const { return x - that.x > -eps && x - that.x < eps; }
        bool operator <= (const Real &that) const { return x - that.x < eps; }
        bool operator >= (const Real &that) const { return x - that.x > -eps; }
    
        friend ostream& operator << (ostream &out, const Real &val) {
            out << val.x;
            return out;
        }
        friend istream& operator >> (istream &in, Real &val) {
            in >> val.x;
            return in;
        }
    };
    
    
    struct Point {
        Real x, y;
        int read() { return scanf("%lf%lf", &x.x, &y.x); }
        Point(const Real &x, const Real &y) { this->x = x; this->y = y; }
        Point() {}
        Point operator + (const Point &that) const { return Point(this->x + that.x, this->y + that.y); }
        Point operator - (const Point &that) const { return Point(this->x - that.x, this->y - that.y); }
        Real operator * (const Point &that) const { return x * that.x + y * that.y; }
        Point operator * (const Real &that) const { return Point(x * that, y * that); }
        Point operator / (const Real &that) { return Point(x / that, y / that); }
        Point operator += (const Point &that)  { return Point(this->x += that.x, this->y += that.y); }
        Point operator -= (const Point &that)  { return Point(this->x -= that.x, this->y -= that.y); }
        Point operator *= (const Real &that)  { return Point(x *= that, y *= that); }
        Point operator /= (const Real &that) { return Point(x /= that, y /= that); }
    
        bool operator == (const Point &that) const { return x == that.x && y == that.y; }
    
        Real cross(const Point &that) const { return x * that.y - y * that.x; }
        Real abs() { return sqrt((x * x + y * y).get()); }
    };
    typedef Point Vector;
    
    struct Segment {
        Point a, b;
        Segment(const Point &a, const Point &b) { this->a = a; this->b = b; }
        Segment() {}
        bool intersect(const Segment &that) const {
            Point c = that.a, d = that.b;
            Vector ab = b - a, cd = d - c, ac = c - a, ad = d - a, ca = a - c, cb = b - c;
            return ab.cross(ac) * ab.cross(ad) < 0 && cd.cross(ca) * cd.cross(cb) < 0;
        }
        Point getSegmentIntersection(const Segment &that) const {
            Vector u = a - that.a, v = b - a, w = that.b - that.a;
            Real t = w.cross(u) / v.cross(w);
            return a + v * t;
        }
        Real Distance(Point P) {
            Point A = a, B = b;
            if (A == B) return (P - A).abs();
            Vector v1 = B - A, v2 = P - A, v3 = P - B;
            if (v1 * v2 < 0) return v2.abs();
            if (v1 * v3 > 0) return v3.abs();
            return v1.cross(v2).abs() / v1.abs();
        }
        bool containPoint(const Point &p) const {
            Vector ap = p - a, bp = p - b;
            return ap * bp < 0;
        }
    };
    
    struct Line {
        Point p;
        Vector v;
        Line(Point p, Vector v): p(p), v(v) {}
        Line() {}
        Point point(Real a) {
            return p + v * a;
        }
    };
    struct Circle {
        Point c;
        Real r;
        Circle(Point c, Real r): c(c), r(r) {}
        Circle() {}
        void read() {
            c.read();
            scanf("%lf", &r.x);
        }
        Point point(Real a) {
            return Point(c.x + r * cos(a.get()), c.y + r * sin(a.get()));
        }
        int getLineIntersection(Line L, vector<Point> &sol) {
            Circle C = *this;
            Real a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
            Real e = a * a + c * c, f = (a * b + c * d) * 2, g = b * b + d * d - C.r * C.r;
            Real delta = f * f - e * g * 4;
            Real t1, t2;
            if (delta < 0) return 0;
            if (delta == 0) {
                t1 = t2 = -f / (e * 2); sol.push_back(L.point(t1));
                return 1;
            }
            t1 = (-f - sqrt(delta.get())) / (e * 2); sol.push_back(L.point(t1));
            t2 = (-f + sqrt(delta.get())) / (e * 2); sol.push_back(L.point(t2));
            return 2;
        }
        Real turningAngle(Point a, Point b) {
            Vector ca = a - c, cb = b - c;
            if (ca.abs() == 0 || cb.abs() == 0) return 0;//一个点和圆心重合,计算转角是没意义的
            Real angle = acos((ca * cb / ca.abs() / cb.abs()).get());
            return ca.cross(cb) >= 0? angle : -angle;
        }
    };
    
    const int maxn = 1e3 + 7;
    
    Point p[maxn];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        int n;
        while (cin >> n, n) {
            for (int i = 0; i < n; i ++) {
                p[i].read();
            }
            Circle c;
            c.read();
            vector<Point> vs;
            for (int i = 0; i < n; i ++) {
                vs.pb(p[i]);
                vector<Point> v;
                Point a = p[i], b = p[(i + 1) % n];
                c.getLineIntersection(Line(a, b - a), v);
                for (int i = 0; i < v.size(); i ++) {
                    if (Segment(a, b).containPoint(v[i])) vs.pb(v[i]);
                }
            }
            Real ans = 0;
            for (int i = 0; i < vs.size(); i ++) {
                int j = (i + 1) % vs.size();
                Point mid = (vs[i] + vs[j]) * 0.5;
                Real length = (mid - c.c).abs();
                if (length < c.r) ans += (vs[j] - vs[i]).abs();
                else ans += c.r * -c.turningAngle(vs[i], vs[j]);
            }
            cout << (ll)(ans.get() + 0.5) << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    mysql复习
    常用函数
    contos7上安装rabbitmq
    linux笔试题
    发布脚本
    Arch最小化安装LXDE桌面环境
    Arch最小化安装X
    Arch安装详解
    Gentoo解决Windows双系统时间不同步的问题
    Gentoo安装详解(五)-- 安装X桌面环境
  • 原文地址:https://www.cnblogs.com/jklongint/p/4831112.html
Copyright © 2020-2023  润新知