There is a lemon tree composed of a cone and a circle. Under the parallel light emitted by the moon, a shadow can be formed to find the area of the shadow.
Idea: understanding the nature of projection: as long as it is a parallel light, it is projected on the horizontal plane, and the resulting images are all the same as the original images.
When we know this, we can draw a picture and analyze it. In fact, the shadow of the lemon tree is the sum of the area of the garden and the isosceles trapezoid. (Example)
Using the knowledge of computational ry, we can obtain the equation of the circle and the equation of the Public tangent of the circle, and then obtain a continuous function. At last, this question becomes the analytical expression of the function, and calculates the area between the function and the X axis.
Apply the Simpson points: Simpson (L, R) = (f (l) + f (r) + f (MID) * 4) * (R-l)/6.0, then, recursively check the accuracy. If the absolute value of the Left value + the right value is smaller than the precision, return the Left area and the right area. An Approximate exact value is the answer.
Code:
#include <cmath>#include <cstdio>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define MAX 10000#define EPS 1e-6#define INF 0x7f7f7f7fusing namespace std;struct Circle{double length,r;}circle[MAX];struct Line{double k,b;double st,ed;}line[MAX];int cnt;double alpha,start,end;int lines;double temp;double GetArea(double l,double r,double _area);double Simpson(double l,double r);double F(double x);int main(){cin >> cnt >> alpha;alpha = 1.0 / tan(alpha);cnt++;for(int i = 1;i <= cnt; ++i) {scanf("%lf",&temp);circle[i].length = circle[i - 1].length + temp * alpha;}for(int i = 1;i <= cnt; ++i)for(int j = i + 1;j <= cnt; ++j) {}start = end = circle[cnt].length;for(int i = 1;i < cnt; ++i) {scanf("%lf",&circle[i].r);start = min(start,circle[i].length - circle[i].r);end = max(end,circle[i].length + circle[i].r);}for(int i = 1;i < cnt; ++i) {if(circle[i + 1].length - circle[i].length - fabs(circle[i + 1].r - circle[i].r) < EPS)continue;double sin_a = (circle[i + 1].r - circle[i].r) / (circle[i + 1].length - circle[i].length);double cos_a = sqrt(1.0 - sin_a * sin_a);double tan_a = sin_a / cos_a;Line *l = &line[++lines];l->st = circle[i].length - circle[i].r * sin_a;l->ed = circle[i + 1].length - circle[i + 1].r * sin_a;l->k = tan_a;l->b = circle[i].r * cos_a - l->st * tan_a;}cout << fixed << setprecision(2) << 2.0 * GetArea(start,end,Simpson(start,end)) << endl;return 0;}double GetArea(double l,double r,double _area){double mid = (l + r) / 2.0;double l_area = Simpson(l,mid),r_area = Simpson(mid,r);if(fabs(l_area + r_area - _area) < EPS)return _area;return GetArea(l,mid,l_area) + GetArea(mid,r,r_area);}double Simpson(double l,double r){double mid = (l + r) / 2.0;return (F(l) + 4.0 * F(mid) + F(r)) * (r - l) / 6.0;}double F(double x){double re = 0.0;for(int i = 1;i <= lines; ++i)if(x <= line[i].ed && x >= line[i].st)re = max(re,line[i].k * x + line[i].b);for(int i = 1;i <= cnt; ++i) if(x <= circle[i].length + circle[i].r && x >= circle[i].length - circle[i].r)re = max(re,sqrt(circle[i].r * circle[i].r - (circle[i].length - x) * (circle[i].length - x)));return re;}
Bzoj 1502 Noi 2005 month-old Lemon Tree Calculation geometric adaptive Simpson points