天天看點

手動計算 ACM

手動計算 ACM

題目描述

LF是一個計算幾何大佬,他每天都要做114514道幾何題來鍛煉自己的計算幾何能力。但是今天LF做剩一道題的時候他竟然發現他這道題他不會做,這道題的題意是這樣的:

平面上有兩個橢圓,這兩個橢圓的中心都是(0,0),且一個橢圓的兩個焦點在x軸上,一個橢圓的兩個焦點在y軸上,給出這兩個橢圓的方程,求他們面積的并的大小。

這道題實在是太難了,于是LF找到了你,你能幫他完成這個艱巨的任務嗎?

輸入描述:

輸入第一行一個整數T\ (1 \leq T \leq 5)T (1≤T≤5),表示資料組數。

接下來共T行,每行四個實數a,b,c,d,表示第一個橢圓的方程為\frac{x2}{a2} +\frac{y2}{b2}=1

a

2

x

2

+

b

2

y

2

=1,第二個橢圓的方程為\frac{x2}{c2} +\frac{y2}{d2}=1

c

2

x

2

+

d

2

y

2

=1, 資料保證a,b,c,d最多兩位小數, 且1 \leq b<a\leq 8,1 \leq c<d\leq 81≤b<a≤8,1≤c<d≤8。

輸出描述:

輸出共T行,每行一個實數表示該組資料中這兩個橢圓面積的并的大小,保留一位小數。

示例1

輸入

複制

3

2 1 1 2

3 2 1 2

3 2 1 4

輸出

複制

8.9

18.8

23.9

做法:定積分

求除兩個橢圓焦點的橫坐标(方程聯立),計算第一象限内兩個橢圓交集的面積(定積分(a,b,c,d,x0都被視為常數)),交集的面積等于兩個橢圓分别在0到x0和x0到c的積分相加

總共的交集面積是第一象限的4倍

求出兩個橢圓的面積,減去交集的面積

手動計算 ACM

特殊情況,一個橢圓包含在另一個橢圓,獨立判斷

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

const double PI = 3.1415926535;
/*
3
2 1 1 2
3 2 1 2
3 2 1 4
*/
int main(void)  {
	int t;
	cin >> t;
	while (t--) {
		double a, b, c, d, ans = 0;
		cin >> a >> b >> c >> d;
		if (a > c && b > d) {
			ans = PI * a * b;
		} else if (c > a && d > b) {
			ans = PI * c * d;
		} else {
			double x0 = sqrt((a*a * c*c * (b*b - d*d))/(b*b * c*c - a*a * d*d));
			double s1 = 0.5 * a * b * (x0 / a) * sqrt(1 - x0*x0 / (a*a)) + 0.5 * a * b * (asin(x0 / a));
			double s2 = PI * c * d / 4 -  0.5 * c * d *  x0 / c * sqrt(1 - x0 * x0 / (c * c)) - 0.5 * c * d * asin(x0 / c);
			ans = PI * a * b + PI * c * d - 4 * (s1 + s2);
		}
		printf("%.1f\n", ans);
	}
}