BZOJ 1502 NOI 2005 月下柠檬树 计算几何 自适应辛普森积分

题目大意:有一个由圆锥和圆台组成的柠檬树,在月亮发出的平行光下,可以形成一个影子,求这个影子的面积。

思路:理解投影的性质:只要是平行光线,投影在水平面上,所得的图形都与原图形全等。

知道了这一点我们就可以画画图,分析就知道,其实柠檬树的影子,就是一些园和等腰梯形的面积的并。(如下图,样例)

运用计算几何的知识就可以得到圆的方程和圆的公切线的方程,然后得到一个连续的函数。最后这个题就成为一直函数的解析式,求这个函数与X轴之间的面积。

套用辛普森积分:Simpson(l,r) = (F(l) + F(r) + F(mid) * 4) * (r - l) / 6.0,然后递归检查精度,如果左值+右值-总值的绝对值小于精度就返回,否则就递归返回左侧面积和右侧面积。得到一个近似精确的值就是所求的答案。

CODE:

#include <cmath>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 10000
#define EPS 1e-6
#define INF 0x7f7f7f7f
using 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;
} 
时间: 2024-08-15 07:21:09

BZOJ 1502 NOI 2005 月下柠檬树 计算几何 自适应辛普森积分的相关文章

【BZOJ-1502】月下柠檬树 计算几何 + 自适应Simpson积分

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 562[Submit][Status][Discuss] Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度.第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的

[BZOJ 1502][NOI2005]月下柠檬树(自适应Simpson积分)

Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看到在月光的照射下柠檬树投在地面上的影子是如此的清晰,马上想到了一个问题:树影的面积是多大呢? 李哲知道,直接测量面积是很难的,他想用几何的方法算,因为他对这棵柠檬树的形状了解得非常清楚,而且想好了简化的方法. 李哲将整棵柠檬树分成了 n 层,由下向上依次将层编号为 1,2,...,n.从第

[NOI2005]月下柠檬树[计算几何(simpson)]

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1169  Solved: 626[Submit][Status][Discuss] Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度.第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的

BZOJ 1502 NOI2005 月下柠檬树 Simpson自适应公式

题目大意:给定一棵由圆台和圆锥构成的柠檬树,月光以α的夹角平行射向地面,求阴影部分面积 补充题目大意:看到这题我产生了心理阴影,求阴影部分面积 题目不好分析,但其实就是求一堆圆和一堆梯形的面积交 样例如图(画的有点烂),将顶点看做半径为0的圆,则图中圆的半径即为给定圆的半径,圆心距为h/tan(α),直线为两圆公切线 这题我们采用辛普森自适应公式 首先辛普森公式见度受百科 http://baike.baidu.com/view/2710883.htm?fr=aladdin 比较遗憾的是 辛普森公

BZOJ 1502:月下柠檬树

BZOJ 1502:月下柠檬树 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题目大意:给出一棵有圆台构成的树以及一个平行光源,问树的阴影面积. 计算几何 Simpson积分 第一次写计算几何题,一直wa...明天补

BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status][Discuss] Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度.第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的

[BZOJ1502]月下柠檬树(自适应辛普森积分)

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1387  Solved: 739[Submit][Status][Discuss] Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地 坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月光的照射下 柠檬树投在地面上的影子是如此的清晰,马上想到了一个问

【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分

[BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月光的照射下柠檬树投在地面上的影子是如此的清晰,马上想到了一个问题:树影的面积是多大呢?李哲知道,直接测量面积是很难的,他想用几何的方法算,因为他对这棵柠檬树的形状了解得非常清楚,而且想好了简化的方法.李哲将整棵柠檬树分成了n 层,由下向

BZOJ 1502 [NOI2005]月下柠檬树 自适应Simpson积分

题意:链接 方法:自适应Simpson积分 解析: 大半夜刷这道题真是爽歪歪. 求一棵树(圆锥加圆台组成)在平面上的投影的面积. 给定投影角度(0.3 < alpha <= pi/2). 先来想想圆的投影是什么样子 还是他自己. 再想圆锥投影是什么样子 一个点加一个圆,并且有这个点与该圆的两条切线(该点在圆内部时没有切线) 再想圆台 两个圆,加上两个圆的外公切线组成的一坨图形. 不妨随意画一个. 好难画- -! 大概就转化成这个样子了. 观察这个图形- 轴对称啊- -! 这意味着我们好多东西都