题目的意思就是第一行给你三个数字.椭圆的个数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));
}
}