题意:如题

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

  • 在圆内,答案加上此边长
  • 在圆外,答案加上此边相对于圆心的"有向转弧"
#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_JUDGEfreopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGEint 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;
}

转载于:https://www.cnblogs.com/jklongint/p/4831112.html

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

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

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

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

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

  3. php面向过程求圆 三角形 长方形计算,求,圆,三角形,长方形,梯形的面积,周长公式...

    这里有很多公式慢慢看吧: 1 每份数×份数=总数 总数÷每份数=份数 总数÷份数=每份数 2 1倍数×倍数=几倍数 几倍数÷1倍数=倍数 几倍数÷倍数=1倍数 3 速度×时间=路程 路程÷速度=时间 ...

  4. JS 函数 求圆的面积总结

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. YTU 2723: 默认参数--求圆的面积

    2723: 默认参数--求圆的面积 时间限制: 1 Sec  内存限制: 128 MB 提交: 206  解决: 150 题目描述 根据半径r求圆的面积, 如果不指定小数位数,输出结果默认保留两位小数 ...

  6. matlab 求圆的周长和面积

    求圆的周长和面积 clc; clear; radius=3; c=2*pi*radius; s=pi*radius*radius; c,s 运行结果c = 18.8495559215388 s = 2 ...

  7. Android 求圆的面积

    计算机应用112班  孔秋静 在Android中实现求圆的面积. 在Layout 中添加一个EditText控件并将它的ID设为e1,添加一个TextViw控件并设置它的ID为t1,添加一个Butto ...

  8. 简单的C++程序求圆的周长和面积

    C++程序求圆的周长和面积 求圆的周长和面积 方法1:用结构化方法编程,求圆的周长和面积 方法2:用面向对象方法编程,求圆的周长和面积 初学者易犯错误模型 求圆的周长和面积 数据描述: 半径,周长,面 ...

  9. 给定圆的半径r,求圆的面积。

    //编写人:yike //时间:2021/1/25/12:28 //问题描述 //给定圆的半径r,求圆的面积. //输入格式 //输入包含一个整数r,表示圆的半径. //输出格式 //输出一行,包含一 ...

最新文章

  1. linux下载哪个python版本-Linux安装多个Python版本
  2. saltstack/salt的state.sls的使用
  3. 成功解决 修改pip的默认安装packages包的路径
  4. 【深度学习】揭秘2021抖音和快手APP图像修复背后的核心技术,毫无ps痕迹
  5. 【MFC】工具栏按钮多选效果本
  6. Oracle role and user privileges
  7. 编程工作怎么样手工问号
  8. 【Java】【编译】javac编译源代码时,若源文件使用了别的java源代码的函数,javac会自动关联。...
  9. (转)Android 如何建立你的菜单
  10. My thoughts after NOIP 2018(2)
  11. zetoro导入csl 软件学报
  12. EasyStack郭长波连任OpenStack基金会独立董事
  13. python下载文件的11种方式_python 下载文件的多种方法汇总
  14. 超市收银系统-Java Swing版
  15. 第八章 项目质量管理
  16. 局域网即时通讯Active Messenger 完美破解版本 最新版本破解
  17. 基于SSM的医院科室人员管理系统
  18. echarts-JSON请求数据
  19. SYN5301型 时间检定仪
  20. Cunti 使用简介

热门文章

  1. ocx开发经验,ActiveX开发快速入门
  2. Windows(win10)添加网络黑名单方法 (禁止某个应用上网)
  3. 链式前向星--最通俗易懂的讲解
  4. 【数学】基本代数图论 Basic Algebraic Graph Theory
  5. 如何获取可靠的国外服务器IP地址?
  6. 【项目】文件加密工具
  7. 数据库-MYSQL安装配置和删除
  8. 2013年5月22日 Dave 在深圳
  9. 电话拨号防盗报警器系统设计
  10. Opencv直方图均衡