问题描述
在一个平面上给定 n 个同心圆。
如下图所示:
这些同心圆构成的图形是蓝黄相间的,其中最外面的圆是蓝色。
请问,这 n 个同心圆构成的图形中,蓝色部分的总面积是多少?
输入格式:
第一行包含整数 n n n。
第二行包含 n n n个整数, r 1 , r 2 , … , r n r1,r2,…,rn r1,r2,…,rn,表示各个圆的半径。
输出格式:
输出蓝色部分的总面积。
结果保留六位小数。
数据范围
1
≤
n
≤
100
,
1≤n≤100,
1≤n≤100,
1
≤
r
i
≤
1000
,
1≤ri≤1000,
1≤ri≤1000,
所有圆的半径两两不同。
输入样例1:
1
1
输出样例1:
3.141593
输入样例2:
3
1 4 2
输出样例1:
40.840704
思路
1、通过分析给出的数据范围,直接暴力即可。排序的复杂度O(nlogn),求和面积复杂度O(n)
2、这题要求的精度是6位,所以PI的小数点要取长一点,一般可以通过math库中的acos函数来计算PI的值,因为cosPI = -1,所以acos(-1) = PI,lf的精度默认输出为6位,如果想输出更多位,控制占位符即可,比如%.20lf即可。
3、这里的求解问题属于小学数学的范畴,圆环面积:外圆面积-内圆面积(外圆半径r > 内圆半径) 公式: S 环 = π ( R ² − r ² ) S环=π(R²-r²) S环=π(R²−r²)
4、因为输入数字大小不是有序的,所以要先进行排序,由于从外往里计算,所以要按从大到小的顺序,sort()函数默认是升序的,即从小到大,但是可以通过传入自定义cmp函数来改变排序的规则,这里传入的是greater<T>()
即由大到小排序,默认是less<T>()
,需要注意一下。
4、注意涂色从外往里涂色,即先蓝色,后黄色,依次交替。所以每次只计算一个最外层蓝色的面积,每次i + 2 往里面迭代来求和即可。
5、不需要考虑最终越界的情况,r[N]数组开在了堆中,默认初始化为0,所以最终的面积是0,不用考虑。
C++代码:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI = acos(-1);
const int N = 110;
int r[N];
int n;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &r[i]);
sort(r, r + n, greater<int>());
double res = 0;
for (int i = 0; i < n; i += 2 )
res += (PI * r[i] * r[i] - PI * r[i + 1] * r[i + 1]);
printf("%lf", res);
return 0;
}