• ZOJ 1104 Leaps Tall Buildings


    题目大意:给出一些建筑物的高度与宽度,求出一条最矮的抛物线运动轨迹,能够跨过所有的建筑物。

    输出初速度与水平方向的夹角,以及初速度的大小。

    重力加速度取9.8m/(s^2)

    思路:

    因为该抛物线过固定点(0,0)和(D,0)(D为所有建筑物宽度之和),故设抛物线方程为:

    y = A * x * ( x - D )

    建立直角坐标系,得到最高的那一圈点的坐标。

    例如第二组样例:

    0 10.5

    20 11.5

    25 10

    10 15

    0 7

    其对应坐标为:

    (10.500000, 20.000000)

    (22.000000, 25.000000)

    (32.000000, 25.000000)

    (47.000000, 10.000000)

    (54.000000,  0.000000)

    从第一个点枚举到第 n-1 个点求得不同的A,分别验证是否满足条件,在满足条件的抛物线中选择顶点最小的那一条。

    角度angle = arctan(抛物线在(0,0)点的导数);

    运用高中物理知识……

    (g*t*t) / 2 = 抛物线顶点高度  =>   求出 t

    速度= g * t / sin(angle)

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 const int MAXN = 100 + 10;
     5 const double INF = 1 << 30;
     6 const double PI = acos(-1);
     7 
     8 struct point
     9 {
    10     double x, y;
    11 };
    12 
    13 int n;
    14 double A, D;
    15 double maxHeight;
    16 point P[MAXN];
    17 double h[MAXN], d[MAXN];    //开始的时候一定要分开保存,我一开始直接读的点的坐标,结果WA了好几次
    18 
    19 double getA( double x, double y )   //根据第三个坐标点得到A的值
    20 {
    21     return y / ( x * ( x - D ) );
    22 }
    23 
    24 double getY( double x, double tpA )  //根据当前的抛物线方程,给出横坐标x,返回纵坐标y
    25 {
    26     return tpA * x * ( x - D );
    27 }
    28 
    29 double Judge( double tpA )          //判断该抛物线是否满足条件
    30 {
    31     for ( int i = 1; i < n; i++ )
    32     {
    33         double tt = getY( P[i].x, tpA );
    34         if ( tt < P[i].y ) return -1;   //如果该x对应抛物线上的y值 小于该点坐标的y值,则不符合条件
    35     }
    36 
    37     double pp = getY( D/2.0, tpA );
    38     return pp;                     //若满足,返回最高点高度
    39 }
    40 
    41 void FindMin()
    42 {
    43     D = d[n];
    44     maxHeight = INF;
    45     for ( int i = 1; i < n; i++ )
    46     {
    47         double H;
    48         double tpA = getA( P[i].x, P[i].y );
    49 
    50         H = Judge( tpA );
    51 
    52         if ( H > 0 && H < maxHeight )       //如果该抛物线符合条件,并且小于当前的最大值,则更新
    53         {
    54             maxHeight = H;
    55             A = tpA;
    56         }
    57     }
    58     return;
    59 }
    60 
    61 int main()
    62 {
    63     d[0] = h[0] = 0;
    64 
    65     while ( scanf("%d", &n) != EOF )
    66     {
    67         double a;
    68         for ( int i = 1; i <= n; i++ )
    69         {
    70             scanf("%lf%lf", &h[i], &a);
    71             d[i] = d[i - 1] + a;
    72         }
    73 
    74         for ( int i = 1; i < n; i++ )         //得到最外面那一圈点的坐标
    75         {
    76             P[i].x = d[i];
    77             P[i].y = h[i] > h[i + 1] ? h[i] : h[i + 1];   
    78         }
    79 
    80         FindMin();
    81 
    82         double angle = atan( - A * D );       //这里得到的角度是弧度,还应当转化一下
    83 
    84         double temp = A * ( D/2.0 ) * ( D/2.0 - D );
    85         double t = sqrt( temp / 4.9 );
    86         double v = 9.8 * t / sin(angle) ;
    87 
    88         printf("%.2f %.2f\n", angle * 180 / PI,  v);
    89 
    90     }
    91 
    92     return 0;
    93 }
  • 相关阅读:
    pycharm中使用redis模块入门
    ubuntu sudo apt-get update与sudo apt-get upgrade的作用及区别,以及python pip的安装
    pycharm修改快捷键
    python2.7.5安装docker-compose的方法
    (二)影响持续交付的因素
    (一)持续交付的定义与价值
    CentOS6的/etc/rc.local不执行的问题解决
    Redis集群进阶之路
    好文收集(长期更新)
    MongoDB如何释放空闲空间?
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/2610660.html
Copyright © 2020-2023  润新知