uvalive4062

来源:互联网 发布:ps磨皮滤镜mac中文版 编辑:程序博客网 时间:2024/06/09 13:53

题目的意思就是第一行给你三个数字.椭圆的个数n,椭圆的离心率e,和椭圆的倾斜角t.

接下n行是每个椭圆的圆心..

每个椭圆面积要一样大,并且互相碰不到,问这个面积最大是多少..


这题简直考高中数学,为了做这题,翻了好多好多圆锥曲线的公式...

首先是

p[i].x = x * cos(r) + y * sin(r);
p[i].y = -x * sin(r) + y * cos(r);

这是一个旋转变化.把椭圆变成正的椭圆..这样才可以比较.

现在就是遍历比较所有两个相邻的圆心..它们要怎么样的面积才不会互相碰到.找到最小的.

按横坐标比一次,再按纵坐标比一次.(因为存在长短轴,所以要比两次)

然后就是关于两点作为圆心,椭圆面积的公式:

首先是长轴a ,短轴b 与 离心率e 的关系有 

所以b/ a =sqrt ( 1 - e * e ); 我们设为 k 吧.

椭圆面积是πab ,因为e已知..所以我们只要知道a平方就行 ,这样面积就等于 π * k * a平方.

所以我们要做的就是已知两个椭圆的圆点和斜率,求两椭圆相切时 的 a平方.

temp1 = fabs(a.x - b.x) / 2;
temp2 = fabs(a.y - b.y) / 2;

算出两个点的中心位置,肯定是两个椭圆的切点(因为两个椭圆完全一样,肯定对称.)

然后问题又变成了.已知椭圆的离心率,和椭圆上的一个点.求椭圆面积.

那就好办了.

c平方 = a平方 - b平方.

e = c /  a ;

椭圆标准方程,x平方 / a 平方 + y平方 / b平方 = 1.

那么c 可以用 a ,e表示 ,b 可以用 a ,c 表示.那么也就是用a ,e.

那么整个方程就只剩 x y a  e ,其中e已知.x ,y为刚才求出的点的坐标,代入就能求出a了..

那么a和 e知道就能求面积了....


AC代码:



 

#include<stdio.h>#include<cmath>#include<algorithm>using namespace std;const double  PI = acos(-1.0);const int N = 15005;struct point {double x;double y;}p[N];int n;double e,t,r;double x,y;int cmp1 (point a ,point b) {return a.x < b.x ;}int cmp2 (point a, point b) {return a.y < b.y ;}double cul (point a ,point b) {double temp1 ,temp2;double temp3 = 1 - e * e;temp1 = fabs(a.x - b.x) / 2;temp2 = fabs(a.y - b.y) / 2;return (temp3 * temp1 * temp1 + temp2 * temp2) / temp3;}int main () {int cas = 1;while (scanf("%d%lf%lf",&n,&e,&t) && n) {double res = 100000000000;r = t * PI / 180;for (int i = 0 ; i < n;i++) {scanf("%lf%lf",&x,&y);p[i].x = x * cos(r) + y * sin(r);p[i].y = -x * sin(r) + y * cos(r);}sort(p ,p + n ,cmp1);double temp ;for (int i = 0 ; i < n - 1 ;i++) {temp = cul (p[i] ,p[i + 1]);res = temp < res ? temp : res;}sort(p ,p + n ,cmp2);for (int i = 0 ; i < n - 1 ;i++) {temp = cul (p[i] ,p[i + 1]);res = temp < res ? temp : res;}printf("Case %d:\n%.6lf\n",cas++,res * PI * sqrt(1 - e * e));}}


0 0
原创粉丝点击