题意:如题

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

  • 在圆内,答案加上此边长
  • 在圆外,答案加上此边相对于圆心的"有向转弧"

#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 > ? 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) < && cd.cross(ca) * cd.cross(cb) < ;
}
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 < ) return v2.abs();
if (v1 * v3 > ) 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 < ;
}
}; 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) * , g = b * b + d * d - C.r * C.r;
Real delta = f * f - e * g * ;
Real t1, t2;
if (delta < ) return ;
if (delta == ) {
t1 = t2 = -f / (e * ); sol.push_back(L.point(t1));
return ;
}
t1 = (-f - sqrt(delta.get())) / (e * ); sol.push_back(L.point(t1));
t2 = (-f + sqrt(delta.get())) / (e * ); sol.push_back(L.point(t2));
return ;
}
Real turningAngle(Point a, Point b) {
Vector ca = a - c, cb = b - c;
if (ca.abs() == || cb.abs() == ) return ;//一个点和圆心重合,计算转角是没意义的
Real angle = acos((ca * cb / ca.abs() / cb.abs()).get());
return ca.cross(cb) >= ? angle : -angle;
}
}; const int maxn = 1e3 + ; 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 = ; i < n; i ++) {
p[i].read();
}
Circle c;
c.read();
vector<Point> vs;
for (int i = ; i < n; i ++) {
vs.pb(p[i]);
vector<Point> v;
Point a = p[i], b = p[(i + ) % n];
c.getLineIntersection(Line(a, b - a), v);
for (int i = ; i < v.size(); i ++) {
if (Segment(a, b).containPoint(v[i])) vs.pb(v[i]);
}
}
Real ans = ;
for (int i = ; i < vs.size(); i ++) {
int j = (i + ) % 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 ;
}

[hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长的更多相关文章

  1. 牛客网暑期ACM多校训练营(第三场) J Distance to Work 计算几何求圆与多边形相交面积模板

    链接:https://www.nowcoder.com/acm/contest/141/J来源:牛客网 Eddy has graduated from college. Currently, he i ...

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

    题目传送门 题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积. 分析:这是个阿波罗尼斯圆.既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y ...

  3. HDU - 2892:area (圆与多边形交 求面积)

    pro:飞行员去轰炸一个小岛,给出炸弹落地点的位置信息,以及轰炸半径:按顺时针或者逆时针给出小岛的边界点. 求被轰炸的小岛面积. sol:即是求圆和多边形的面积交. (只会套板子的我改头换面,先理解然 ...

  4. Gym-101158J Cover the Polygon with Your Disk 计算几何 求动圆与多边形最大面积交

    题面 题意:给出小于10个点形成的凸多边形 和一个半径为r 可以移动的圆 求圆心在何处的面积交最大,面积为多少 题解:三分套三分求出圆心位置,再用圆与多边形面积求交 #include<bits/ ...

  5. hdu 5130(2014广州 圆与多边形相交模板)

    题意:一个很多个点p构成的多边形,pb <= pa * k时p所占区域与多边形相交面积 设p(x,y),       (x - xb)^2+(y - yb)^2 / (x - xa)^2+(y ...

  6. A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&判断点在多边形内&判断圆在多边形内)

    题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内.   分析:判断凸多边形可 ...

  7. codeforces 8D Two Friends 二分+ 判断三个圆是否有公共交点

    题目链接 有两个人x, y, 现在在A点, x要直接去B点, y要先去C点在去B点, 现在给出x, y两人可以行走的最大距离T1, T2, 求出他们从A点出发之后, 可以走的最长的公共路径. 我们先看 ...

  8. Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交

    题面 题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交 题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交 打的时候队友说凹的不行,不是板题,后面想想,圆与多 ...

  9. hdu 3982 Harry Potter and J.K.Rowling (半平面交 + 圆与多边形交)

    Problem - 3982 题意就是给出一个圆心在原点半径为R的圆形蛋糕,上面有一个cherry,对蛋糕切若干刀,最后要求求出有cherry的那块的面积占整个蛋糕的多少. 做法显而易见,就是一个半平 ...

随机推荐

  1. asp.net core web api + Element-UI的Vue管理后台

    后端:asp.net core web api + EF Core 前端:VUE + Element-UI+ Node环境的后台管理系统. 线上地址:http://www.wangjk.wang/ 密 ...

  2. SpringCloud-Hystrix 服务降级、熔断

    Hystrix 是什么? Hystrix 是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时.异常等,Hystrix 能够保证在一个依赖出问题的情况下 ...

  3. 磁盘性能测试工具之fio

    fio是测试磁盘性能的一个非常好的工具,用来对硬件进行压力测试和验证. 注意事项 CentOS 6.5等较老版本的操作系统用fdisk创建分区时,默认为非4KB对齐选择初始磁柱编号,对性能有较大的影响 ...

  4. Python常用库-Psutil

    背景 介绍一个处理进程的实用工具,这个是一个第三方库.应用主要有类似ps.cd.top,还有查看硬盘.内存使用情况等. 推荐的理由主要有 2 个,第一个是跨平台的,不管是OSX.Centos.Wind ...

  5. 关于Google下插件SwitchyOmega用法

    开启代理后,尽管访问很自由了,但是我的搬瓦工,是有流量限制的.所以,在之前,我开启一会自由访问模式(戏称),然后关一会,用来方便打开国内网站. 是的,我这么坚持了半个月,之后,就崩溃了,太尼玛繁琐了! ...

  6. Java工作流程引擎系统的退回规则 专题说明

    概述 说明:流程引擎的退回与发送,分别是前进与后退,它是流程引擎的基础功能操作,流程的退回根据不同的应用场景,也是需要不同的方式来控制,我们把这些方式叫做规则处理. 退回工作的场景相对复杂,由于与审核 ...

  7. js判断一个元素是否在数组内

    1.indexOf()返回给定元素在数组内的索引值,如果不存在则返回-1 var arr=[0,1,2,3,4,5] console.log(arr.indexOf(1)) console.log(a ...

  8. Mac home 目录下创建文件夹

    example:sudo vim /etc/auto_master before: # Automounter master map +auto_master # Use directory serv ...

  9. CRS-0184 Cannot communicate with the CRS daemon

    事件背景 rman清理脚本异常.导致磁盘空间爆满(一个环境变量没有设置正确) 释放磁盘空间,进行rman清理 之后,领导把实例重启,但是ams实例没有关闭 环境 系统 : AIX 数据库: Oracl ...

  10. git常用命令/git 部分高级命令备忘录

    常用命令 克隆 - git clone  git@gitee.com:niunafei1/git_learning.git git 创建分支 - git checkout -b dev git 切换分 ...