• HDU 6354--Everything Has Changed(判断两圆关系+弧长计算)


    • 题目
    • 题意:首先给定一个以原点为圆心,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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    SQL的update from 理解
    JS自动合并表格
    完全备份ORACLE数据库 并在另一台电脑上恢复
    cmd 连接到指定路径
    oracle 11g 64位安装sqldeveloper打开不了
    oracle 11g卸载方法
    sql的游标使用(转)
    JQEUERY案例
    sessionStorage实现note的功能
    Web Worker模拟抢票
  • 原文地址:https://www.cnblogs.com/FlyerBird/p/9431703.html
Copyright © 2020-2023  润新知