题目链接:http://acm.bnu.edu.cn/v3/problem_show.php?pid=18165
题目大意:题目的本质就是有一个椭圆,很标准,长轴在x轴,现在从长轴的右端点出发沿着椭圆逆时针走了一段距离,这个点与椭圆的右焦点的连线扫过的面积给出,求现在这个点的坐标。。。
解题思路:看完题目第一感觉就是二分+simpson。然后(就开始犯二了),觉得用极坐标表示椭圆肯定比较好求积分,突然想不起来椭圆的极坐标方程了(自愧不如高中生,想当初也是经常用的。。。)百度之,找到公式之后发现这些符号完全不理解,百度之又出现了一堆的定义,什么离心率,半径,通径,准线,椭圆的各种定义,焦半径。终于看懂了,将F函数写上,算一下积分,靠,竟然不对,检查了n遍代码,还不对。最后终于想到了,积分的形式变了,原来是按照长方形积分,现在是扇形,怎么办??于是仿照长方形的simpson公式写出了一个扇形的公式,果然秒掉样例。从BNUOJ上搜了一下,UVALive UVA SGU都有这道题,于是果断全交了一遍,然后返回了三个结果,分别是TLE WA AC,靠,SGU数据太弱了,调了调精度,UVALive UVA都过不了,应该是不对吧,simpson什么时候提出过这种公式,肯定是自己yy错了,然后老老实实的改成比较普通的方法(就是用直角坐标系),调了调精度,过了UVA,UVALive一直TLE到底是什么鬼!!有意思吗??放弃了
代码,能够通过UVA的代码(本来只是来做simpson模板的。。。结果)
//#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
#define lson k<<1
#define rson k<<1|1
using namespace std;
const int N = 100005;
const db PI = acos(-1.0);
//自适应辛普森
db ep, e;
int ch;
db f(db x)
{
return ep / (1.0 + e * cos(x));
}
db long_, short_;
db long2;
db F(db x)
{
return short_ * sqrt(1.0 - x * x / long2);
}
db simpson(db a, db b, db Fa, db Fb, db &Fc)
{
db c = (a + b) / 2.0;
Fc = F(c);
return (Fa + Fc * 4.0 + Fb) * (b - a) / 6.0;
}
db area(db a, db b, db eps, db A, db Fa, db Fb, db Fc)
{
db c = (a + b) / 2.0;
db Fl, Fr;
db L = simpson(a, c, Fa, Fc, Fl), R = simpson(c, b, Fc, Fb, Fr);
if(fabs(L + R - A) < 15.0 * eps) return L + R + (L + R - A) / 15.0;
return area(a, c, eps / 2.0, L, Fa, Fc, Fl) + area(c, b, eps / 2.0, R, Fc, Fb, Fr);
}
db asr(db a, db b, db eps)
{
db Fa = F(a), Fb = F(b), Fc = F((a + b) / 2.0);
return area(a, b, eps, simpson(a, b, Fa, Fb, Fc), Fa, Fb, Fc);
}
int main()
{
#ifdef PKWV
freopen("in.in", "r", stdin);
#endif // PKWV
int a, b, t, x, y, z;
int cas(1);
while(scanf("%d%d%d%d%d%d", &a, &b, &t, &x, &y, &z) && a + b + t + x + y + z)
{
long_ = x, short_ = y;
long2 = long_ * long_;
db T = sqrt((db)x * (db)x * (db)x / (db)a / (db)a / (db)a * (db)t * (db)t);
db c = sqrt((db)x * (db)x - (db)y * (db)y);
e = c / (db)x;
ep = ((db)y * (db)y) / (db)x;
db l(0.0), r(2.0 * PI);
db eps = 1e-9;
db k = (db)z - floor((db)z / T) * T;
k = k / T;
db tol = (db)x * (db)y * PI;
db S = k * (db)x * (db)y * PI;
while(l + eps < r)
{
db mid = (l + r) / 2.0;
db x = f(mid) * cos(mid) + c;
x = max(x, -long_);
db s = asr(x, long_, eps);
db len = f(mid);
if(mid < PI)
{
s += len * cos(mid) * len * sin(mid) / 2.0;
}
else
{
s = tol - (s - len * cos(mid) * len * sin(mid) / 2.0);
}
if(s < S)
{
l = mid;
}
else r = mid;
}
db dis = f(l);
db xx = c + dis * cos(l);
db yy = dis * sin(l);
printf("Solar System %d: %.3f %.3f\n", cas++, xx, yy);
}
return 0;
}