dw网站建设的基本流程,智慧城市网站建设,wordpress 招聘主题,wordpress tag静态P4207 [NOI2005]月下柠檬树 如图#xff0c;我们要求的面积就是这些圆形跟梯形的组合#xff0c;由于投射到地面上#xff0c;显然有h′htanθh \frac{h}{tan \theta}h′tanθh#xff0c;由此我们就可以开始推导这个f(x)f(x)f(x)函数了。
所以转换为我们要推导出直线a…P4207 [NOI2005]月下柠檬树 如图我们要求的面积就是这些圆形跟梯形的组合由于投射到地面上显然有h′htanθh \frac{h}{tan \theta}h′tanθh由此我们就可以开始推导这个f(x)f(x)f(x)函数了。
所以转换为我们要推导出直线a,ba, ba,b的函数表达式了。
有公切线ababab矩形abgcabgcabgc所以显然有egrc−reeg r_c - r_eegrc−re由三角形acd∼ceg∼befacd \sim ceg \sim befacd∼ceg∼bef由此我们可以得到cd,efcd, efcd,ef从而得到ad,bfad, bfad,bf知道这里对圆公切线问题就已经解决了。
所以接下来我们知道带到函数中利用自适应辛普森求解即可详细细节见代码描述。
/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include bits/stdc.husing namespace std;typedef long long ll;const int inf 0x3f3f3f3f;
const double eps 1e-6;const int N 510;int n;double angle;struct Point {double x, y;
}circle[N], line[N 1];void get_point() {//求得切线的左右两个坐标。for(int i 1; i n; i) {double x1 circle[i].x, x2 circle[i 1].x, r1 circle[i].y, r2 circle[i 1].y;double ce r1 * (r1 - r2) / (x2 - x1), xa x1 ce, ya sqrt(r1 * r1 - ce * ce);double gd r2 * (r1 - r2) / (x2 - x1), xb x2 gd, yb sqrt(r2 * r2 - gd * gd);line[2 * i - 1] {xa, ya}, line[2 * i] {xb, yb};}
}double f(double x) {double ans 0.0;for(int i 1; i n; i) {//在圆里面if(x circle[i].x circle[i].y x circle[i].x - circle[i].y) {ans max(ans, sqrt(circle[i].y * circle[i].y - (x - circle[i].x) * (x - circle[i].x)));}}for(int i 1; i 2 * (n - 1); i 2) {//被切线包围if (x line[i].x x line[i 1].x) {ans max(ans, (line[i 1].y - line[i].y) / (line[i 1].x - line[i].x) * (x - line[i].x) line[i].y);}}//这些值一定是取最大嘛因为它可能同时符合圆切线的要求所以我们得取覆盖面积最大的。return ans;
}double sim(double l, double r) {return (r - l) * (f(l) f(r) f((l r) / 2.0) * 4.0) / 6.0;
}double asr(double l, double r, double eps, double ans) {double mid (l r) / 2.0;double ansl sim(l, mid), ansr sim(mid, r);if(fabs(ansl ansr - ans) 15.0 * eps) return ansl ansr (ansl ansr - ans) / 15.0;return asr(l, mid, eps / 2.0, ansl) asr(mid, r, eps / 2.0, ansr);
}int main() {// freopen(in.txt, r, stdin);// freopen(out.txt, w, stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);scanf(%d %lf, n, angle);angle tan(angle);n;for(int i 1; i n; i) { scanf(%lf, circle[i].x);circle[i].x / angle;//改变x的值求个前缀和得到对应的准确的坐标。circle[i].x circle[i - 1].x;}for(int i 1; i n; i) {scanf(%lf, circle[i].y);}circle[n].y 0;get_point();double l circle[1].x - circle[1].y, r circle[n].x;//确定积分区间。for(int i 1; i n; i) {l min(l, circle[i].x - circle[i].y);r max(r, circle[i].x circle[i].y);}printf(%.2f, 2.0 * asr(l, r, eps, sim(l, r)));return 0;
}