题目大意:
对于特定的tests,
给定n,d,h; n表示的树的数量 d,h表示三角形的底和高
接下来的n个数字,表示树的高度。拿上图举例,即为1,4,5.
计算所有的绿色面积。
先计算每个三角形单独拿出来的面积是多少。设为S。
ans=S*n-CS; CS是重复计算的面积。
把这些三角形按照高度递减的顺序排序。
下面的三角形有可能被遮住,要判断。
我们设两个三角形的两个底之前的间距为xh=height[i]-height[i-1];
if(xh>=h) 两个三角形之前没有重合 CS+=0;
else 因为相似三角形面积比是变比的平方,我们得到一个计算重合部分的式子。
CS=((h-xh)*(h-xh)*S)/(h*h);
最后得到了CS,相减就行了。
还有一个值得注意的点是我在这里用的是long double,然后输出控制6位的方法是引入iomanip库,用fixed+setprecision(6)的方式。
以下是AC代码:
//
// main.cpp
// 1200 A
//
// Created by 汪汪队 on 2023/7/17.
//
#include <iostream>
#include <vector>
#include <math.h>
#include <iomanip>
#define endl "\n"
#define double long double
#define int long long
using namespace std;
void fast(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
return;
}
void test(){
int n,d,h;
cin>>n>>d>>h;
double S=(double)(d*h)/2;
double CS=0;
double ans=n*S;
vector<int>height(n);
for (int i=0; i<n; i++) {
cin>>height[i];
}
sort(height.begin(),height.end());
for (int i=n-1; i>0; i--) {
int xh=h-(height[i]-height[i-1]);
if((height[i]-height[i-1])<h){
CS+=(double)(xh*xh*S)/(h*h);
}
}
cout<<fixed<<setprecision(6)<<(double)(ans-CS)<<endl;
return;
}
signed main() {
fast();
int tests;
cin>>tests;
while (tests--) {
test();
}
return 0;
}