wa33,采用的是减去两个上下三角形的方式,不懂为啥会错
查看原帖
wa33,采用的是减去两个上下三角形的方式,不懂为啥会错
819682
Exile_Code楼主2025/1/4 22:21
#include <bits/stdc++.h>
using namespace std;


#define inf64 INT64_MAX/2
#define inf32 INT32_MAX/2
#define int ll
#define ll long long
#define pii pair<int,int>
#define endl '\n'
#define vv vector
#define cy cout<<"Yes"<<endl
#define cn cout<<"No"<<endl
#define its(a)  a.begin(),a.end()
#define minV *min_element
#define maxV *max_element

int _;
ll lcm(ll a, ll b) { return a / __gcd(a, b) * b; }
//数学公式
ll mpow(ll x, ll y, ll mod);


//计算几何
#define LD long double 
#define PI  3.14159265358979323846
#define eps 1e-8
struct Point {
	LD x, y;
	Point(LD x, LD y) { this->x = x;	this->y = y; }
	Point() {}
#define line Point 
	//点的加减乘运算
	Point operator+(Point b) { return Point(this->x + b.x, this->y + b.y); }
	Point operator-(Point b) { return Point(this->x - b.x, this->y - b.y); }
	Point operator*(LD t) { return Point(this->x * t, this->y * t); }
	LD operator*(Point b) { return this->x * b.x + this->y * b.y; }
	bool operator==(Point b) { return this->x == b.x && this->y == b.y; }
	Point operator/(LD t) { return Point(this->x / t, this->y / t); }
};
struct Line {
	Point s, e;
	ll id;
	bool operator==(Line b) {
		return this->e == b.e && this->s == b.s;
	}
};
struct Circle { Point p; LD r; };
struct Geomtry_tool {

	//求长度
	static LD len(line a) { return sqrtl(a.x * a.x + a.y * a.y); }
	//求两点距离
	LD dis(Point a, Point b) { return sqrtl((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); }
	//两个向量求角度,使用的是余弦定理求arccos
	static LD angle(line a, line b) { return acosl(a * b / len(a) / len(b)); }
	//两个向量求叉积
	static LD cross(line a, line b) { return a.x * b.y - a.y * b.x; }
	//epslion,判断是否等于0
	static int sgn(LD x) { return fabsl(x) <= eps ? 0 : x > 0 ? 1 : -1; }
	//防止负0的发生
	static void zero(Point& a) { if (fabsl(a.x) <= eps)a.x = 0; if (fabsl(a.y) <= eps)a.y = 0; }
	//可以用来判断c在b的左侧还是右侧
	//大于0,c在ab左侧;小于0,c在ab右侧;等于0,三点共线
	static LD cross(Point a, Point b, Point c) { return cross(b - a, c - a); }
	//三点点积ab*ac
	static LD dot(Point a, Point b, Point c) { return (b - a) * (c - a); }
	//判断直线与线段的交点情况,在同侧则无交点;
	//如果是判断线段与线段有无交点,则需要分别设ab,cd为直线,进行两次判断
	static bool l_S_inter(Point a, Point b, Point c, Point d) {
		return sgn(cross(a, b, c) * cross(a, b, d)) <= 0;//直线与线段
	}
	//线段与线段
	static bool S_S_inter(Point a, Point b, Point c, Point d) {
		return l_S_inter(a, b, c, d) && l_S_inter(c, d, a, b);
	}
	//求两直线的交点
	static Point getNode(Point a, line u, Point b, line v) {
		LD t = cross((a - b), v) / cross(v, u);//求面积之比
		return a + u * t;
	}
	//逆时针旋转b
	static Point rotate(Point a, LD b) { //将某点绕原点逆时针旋转b角度
		return { a.x * cosl(b) - a.y * sinl(b), a.x * sinl(b) + a.y * cosl(b) };
	}
	//求多边形面积
	static LD get_S(vv<Point>& p) {
		int k = p.size() - 1; LD res = 0;
		for (int i = 2; i < k; i++)
			res += cross((p[i] - p[1]), (p[i + 1] - p[1]));
		return res / 2;
	}
	//求中垂线
	static Line midperp(Point a, line b) {//求出来的是点向式,而不是两点式
		return { (a + b) / 2,rotate(b - a,PI / 2) };
	}
	//极角排序
	bool cmp1(Point a, Point b) {
		if (atan2l(a.y, a.x) != atan2l(b.y, b.x))
			return atan2l(a.y, a.x) < atan2l(b.y, b.x);
		else return a.x < b.x;
	}
};

void solve() {

	LD r1, r2;
	int x, y, xx, yy;
	cin >> x >> y >> r1 >> xx >> yy >> r2;




	auto nd1 = Point(x, y);
	auto nd2 = Point(xx, yy);
	Geomtry_tool gt;

	LD len_r = gt.dis(nd1, nd2);
	
	if (len_r >= r1 + r2) {
		cout << 0 << endl;
		return;
	}
	else if (len_r <= abs(r1 - r2)) {
		cout << fixed << setprecision(50) << PI * min(r1, r2) * min(r1, r2) << endl;
		return;
	}
	LD dis = len_r;
	long double a1 = acosl((r1 * r1 + dis * dis - r2 * r2) / 2 / dis / r1);
	long double a2 = acosl((r2 * r2 + dis * dis - r1 * r1) / 2 / dis / r2);

	LD a = (r1 * r1 + len_r * len_r - r2 * r2) / 2.0 / r1 / len_r;
	LD thta1 = (LD)2 * acosl(a);
	LD b = (r2 * r2 + len_r * len_r - r1 * r1) / 2.0 / r2 / len_r;
	LD thta2 = (LD)2 * acosl(b);

	LD trigul = r1 * len_r * sinl(thta1/2);//这个算的似乎有问题,不懂为什么不饿能使用这种三角形面积的求解方式,按照的是上下两个三角形拼接的方式
	LD shan = thta1 * r1 * r1 / (LD)2 + thta2 * r2 * r2 / (LD)2;

	LD ans = shan - trigul;
	cout << fixed << setprecision(50) << ans << endl;

}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	_ = 1;
	//cin >> _;

	while (_--) {
		solve();
	}

	return 0;
}


ll mpow(ll x, ll y, ll mod) {
	x %= mod;
	ll s = 1;
	while (y) {
		if (y & 1) {
			s *= x;
			s %= mod;
		}
		x *= x;
		x %= mod;
		y >>= 1;
	}
	return s;
}
2025/1/4 22:21
加载中...