C – Little Jumper (三分)

  • 2019-02-09
  • 0
  • 0

题目链接:https://cn.vjudge.net/contest/281961#problem/C

提问:这题为什么可以用三分呢???
回答:当然是因为随着第一次落地位置的变化v先减后增喽
再次提问:那为什么仅仅通过有一个最小值就可以判断先减后增呢???
再次回答:鬼知道!!!

题意:一条jh要向图中那样跳一下再跳一下,最终落在终点位置,求出在跳的过程中速度最大值中的最小值

思路:再jh跳的过程中肯定是初始时速度最大,所以让两个初始速度中的最大值尽可能小。

先看一个简单问题,一条坐标轴,让jh从x点蹦到y点,问最小需要多大的初速度。
解:……………….
…………………..
…………………..
…………………..
综上所诉,当vx=vy时,也就是v与vx(vy)夹角为45度时,初速度最小。

现在就让jh按照这种最佳答案跳!!!
命运1:jh平安跳过去了,哈哈哈哈,成功获得最小值。
命运2:jh撞到上面的墙摔了下来,虽然不知道时撞死的还是摔死的,但是jh死了!!!这时候最佳跳法不行,为了让jh安全通过并且让初速度尽可能小,就要让jh恰巧通过最上方,因为此时离最佳跳法最近,得到的初速度也最小。
命运3:jh撞到下面的墙死了!!!这时候就让jh恰巧跳过最下方的点。

证明可参考:https://blog.csdn.net/thearcticocean/article/details/51533065

代码:

#include <bits/stdc++.h>

using namespace std;

double b1,t1,b2,t2,l,ds,df,g;
double eps=1e-12;

double cal(double dis,double x,double b,double t)
{
    double v=0;
    double mid=dis/2;
    double a=-1.0/dis;
    double y=a*x*x+x;
    if(y>=b&&y<=t)
    {
        double h=a*mid*mid+mid;
        double t,vx,vy;
        t=sqrt(2*h/g);
        vx=dis/t/2.0;
        vy=g*t;
        v=vx*vx+vy*vy;
    }
    else
    {
        if(y<b)a=b/(x*x-dis*x);
        else a=t/(x*x-dis*x);
        double h=a*mid*(mid-dis);
        double t,vx,vy;
        t=sqrt(2*h/g);
        vx=dis/t/2;
        vy=g*t;
        v=vx*vx+vy*vy;
    }
    return v;
}

double solve(double t)
{
    double x1=ds+t;
    double x2=df+l-t;
    double v1,v2;
    v1=cal(x1,ds,b1,t1);
    v2=cal(x2,l-t,b2,t2);
    return max(v1,v2);
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>b1>>t1>>b2>>t2>>l>>ds>>df>>g)
    {
        double i,j,mid1,mid2;
        i=0,j=l;
        while(j-i>eps)
        {
            mid1=(j+i*2)/3;
            mid2=(i+j*2)/3;
            if(solve(mid1)<solve(mid2))j=mid2;
            else i=mid1;
        }
        printf("%.4f\n",sqrt(solve(mid1)));
    }
    return 0;
}

评论

还没有任何评论,你来说两句吧