• 题目
  • 题意:首先给定一个以原点为圆心,R为半径的圆,之后在给m个圆,这些圆可能会和原来的圆有所交集,计算开始的圆剩余区域的周长,不包括内部周长。
  • 首先判定两圆关系,如果内含,直接加上圆的周长,如果相交,在计算对应弧长,其他情况都不用计算。在计算圆心角的时候,有个精度问题,只用本身半径算出来的弧度会不够,所有用上两个圆的半径。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double PI = acos(-1.0);
typedef struct point {
double x;
double y;
point() { }
point(double a, double b) {
x = a;
y = b;
}
point operator -(const point &b)const { //返回减去后的新点
return point(x - b.x, y - b.y);
}
point operator +(const point &b)const { //返回加上后的新点
return point(x + b.x, y + b.y);
}
//数乘计算
point operator *(const double &k)const { //返回相乘后的新点
return point(x * k, y * k);
}
point operator /(const double &k)const { //返回相除后的新点
return point(x / k, y / k);
}
double operator ^(const point &b)const { //叉乘
return x*b.y - y*b.x;
}
double operator *(const point &b)const { //点乘
return x*b.x + y*b.y;
}
double len() { //返回直角三角形的斜边长
return hypot(x, y);
}
}point;
typedef struct circle {//圆
double r;
point centre;
circle() { }
circle(point a,double b) {
centre = a;
r = b;
}
double len() {
return 2 * PI*r;
}
double area() {
return PI*r*r;
}
}circle;
circle org;
double ans, r;
int t, m;
double dist(point p1, point p2) { //返回平面上两点距离
return sqrt((p1 - p2)*(p1 - p2));
}
int CircleInterNum(circle a, circle b) {
double fh = fabs(a.r + b.r), fc = fabs(a.r - b.r), d = dist(a.centre, b.centre);
if (d>fh)
return -2; //外离,没有交点
if (d==fh)
return -1; //外切,一个交点
if (d > fc&&d < fh)
return 0; //相交,两个交点
if (d == fc)
return 1; //内切,一个交点
if (d < fc&&d>=0)
return 2; //内含,没有交点
} void CircleIntteLen(circle a, circle b) {
double d = dist(a.centre, b.centre);
double t = (d*d + a.r*a.r - b.r*b.r) / (2.0 * d);
double h = sqrt((a.r*a.r) - (t*t))*2;
double angle_a = 2*acos((a.r*a.r +d*d-b.r*b.r) / (2.0 * a.r*d)); //余弦公式计算圆心角,反三角计算出的是弧度
double angle_b = 2*acos((b.r*b.r +d*d-a.r*a.r) / (2.0 * b.r*d));
double la = angle_a*a.r;
double lb = angle_b*b.r;
ans += (lb-la);
}
int main(void) {
cin >> t;
while (t-- > 0) {
org.centre = point(0, 0);
cin >> m >> r;
org.r = r;
ans = org.len();
double x, y, rt;
for (int i = 0; i < m; i++) {
cin >> x >> y >> rt;
circle tmp = circle(point(x, y), rt);
if (CircleInterNum(org, tmp) == 0)
CircleIntteLen(org, tmp);
if (CircleInterNum(org, tmp) == 1)
ans += tmp.len();
}
printf("%.15f\n",ans);
}
return 0;
}

HDU 6354--Everything Has Changed(判断两圆关系+弧长计算)的更多相关文章

  1. c++ 判断两圆位置关系

    对于两圆的位置一般有五种关系: (1) 外离:两圆的半径之和小于两圆圆心距离 (2) 外切:两圆的半径之和等于两圆圆心距离 (3) 相交:两圆的半径之和大于两圆圆心距离,两圆圆心距离大于两圆半径之差 ...

  2. HDU 6354 Everything Has Changed(余弦定理)多校题解

    题意:源点处有个圆,然后给你m个圆(保证互不相交.内含),如果源点圆和这些原相交了,就剪掉相交的部分,问你最后周长(最外面那部分的长度). 思路:分类讨论,只有内切和相交会变化周长,然后乱搞就行了.题 ...

  3. LightOJ 1118--Incredible Molecules(两圆相交)

    1118 - Incredible Molecules      PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Lim ...

  4. 实验12:Problem D: 判断两个圆之间的关系

    Home Web Board ProblemSet Standing Status Statistics   Problem D: 判断两个圆之间的关系 Problem D: 判断两个圆之间的关系 T ...

  5. hdu 1147:Pick-up sticks(基本题,判断两线段相交)

    Pick-up sticks Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. hdu 1086:You can Solve a Geometry Problem too(计算几何,判断两线段相交,水题)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  7. UVa 10674 (求两圆公切线) Tangents

    题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果 ...

  8. HDU 3264 Open-air shopping malls (计算几何-圆相交面积)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3264 题意:给你n个圆,坐标和半径,然后要在这n个圆的圆心画一个大圆,大圆与这n个圆相交的面积必须大于等 ...

  9. 6354 Everything Has Changed

    Edward is a worker for Aluminum Cyclic Machinery. His work is operating mechanical arms to cut out d ...

随机推荐

  1. 静态化HttpClient

    实现方法: public class HttpClientHelper { private static HttpClient _client; public static HttpClient Ge ...

  2. Android之侧滑导航栏

    今天学习的新内容是侧滑导航栏,我想大家肯定都比较熟悉了,因为这个效果在qq里面也有,最近一直跟室友们玩的游戏是快速让自己的头像的点赞量上千.当然我的效果跟qq是没有办法比的,因为那里面的功能是在是太强 ...

  3. TiDB, Distributed Database

    https://www.zhihu.com/topic/20062171/top-answers

  4. JSP初学者5

    JSP中include指令和include动作的区别 include指令是编译阶段的指令,即include所包含的文件的内容是编译的时候插入到JSP文件中,  JSP引擎在判断JSP页面未被修改,否则 ...

  5. 如何获得ImageView中的图像

    我们知道在Android中ImageView是一个用于显示图像的控件,比如在很多联系人方面的应用中,需要为联系人拍摄头像,并将得到的头像放在一个 ImageView对象中显示.通常,在没有为联系人拍摄 ...

  6. JDBC操作数据库的基本步骤:

    JDBC操作数据库的基本步骤: 1)加载(注册)数据库驱动(到JVM). 2)建立(获取)数据库连接. 3)创建(获取)数据库操作对象. 4)定义操作的SQL语句. 5)执行数据库操作. 6)获取并操 ...

  7. Consul在linux系统, 群集实战

    Consul作为微服务的服务注册与发现组件,是非常重要的一部分 目前想用Consul作为配置管理的统一管理 准备两台机器 11.11.11.1011.11.11.20 下载consul linux版  ...

  8. C# 轻松读取、改变文件的创建、修改、访问时间 z

    // 读取文件的创建.修改.访问时间FileInfo fi = new FileInfo("C://test.txt");Console.WriteLine(fi.Creation ...

  9. Linux中如何安装配置Mysql和SVN服务端

    目标Linux系统为centOS 一.安装登陆mysql   1.直接以root用户运行:yum install mysql 和yum install mysql-server等带安装完成. 2.安装 ...

  10. Andriod ADB Interface驱动安装失败Configure USB Debug for Android

    介绍: Linux或Apple或OS X ,已经安装了USB驱动调试为Android的帮助,确认您的Android USB调试连接配置和正常工作. Windows下需要自己手动下载驱动安装或者通过下载 ...