The Solar System

题目链接: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;
}


猜你喜欢

转载自blog.csdn.net/u014076176/article/details/45133761