http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=2830
题目大意:空中有很多竖直的门,一个点以V0的初速度抛出,忽略空气阻力,重力加速度为10m/s 2,求此点最多能穿过几个门。
解法:对于每个门,根据斜抛运动,解出初速度与x轴的夹角范围,然后求出重叠次数最大的区域,输出该次数。

eoj 2830
  1#include <cstdio>
  2#include <iostream>
  3#include <cstring>
  4#include <complex>
  5#include <string>
  6#include <algorithm>
  7#include <vector>
  8#include <cmath>
  9using namespace std;
 10
 11const int maxn = 20005;
 12const double eps = 1e-8;
 13const double inf = 1e20;
 14const double pi = acos( -1.0 );
 15const double g = 10.0;
 16
 17struct node
 18{
 19    double angle1, angle2;
 20}
ang[ maxn << 1 ];
 21
 22int D( double x ) return ( x < -eps ? -1 : x > eps ); }
 23
 24bool cmp( const node & a, const node & b )
 25{
 26    if( D( a.angle1 - b.angle1 ) != 0 ) return a.angle1 < b.angle1;
 27    return D( a.angle2 - b.angle2 ) < 0;
 28}

 29
 30
 31//double y1[ maxn ], y2[ maxn ];
 32//double x[ maxn ];
 33 
 34int main(int argc, char *argv[])
 35{
 36    int cas, v0, n;
 37    double a, b, c, t, x, y1, y2, data;
 38    double angle1, angle2, angle3, angle4;
 39    scanf("%d",&cas);
 40    while( cas-- )
 41    {
 42        scanf("%lf%d",&v0,&n);
 43        int len = 0;
 44        forint i = 0; i < n; i++ )
 45        {
 46            scanf("%lf%lf%lf",&x,&y1,&y2);
 47            a = g * ( x / v0 ) * ( x / v0 ) / 2.0 ;
 48            b = -x;
 49            c = y1 + a;
 50            data = b * b - 4 * a * c ;
 51            if( D( data ) >= 0 )
 52            {
 53                if( data < 0 ) data = 0;
 54                t = sqrt( data );
 55                angle1 = ( -- t ) / 2.0 / a ;
 56                angle2 = ( -+ t ) / 2.0 / a ;
 57            }

 58            else continue;
 59            a = g * ( x / v0 ) * ( x / v0 ) / 2.0 ;
 60            b = -x ;
 61            c = y2 + a ;
 62            data = b * b - 4 * a * c ;
 63            if( D( data ) >= 0 )
 64            {
 65                if( data < 0 ) data = 0;
 66                t = sqrt( data );
 67                angle3 = ( -- t ) / 2.0 / a ;
 68                angle4 = ( -+ t ) / 2.0 / a ;
 69                ang[ len ].angle1 = angle1;
 70                ang[ len ].angle2 = angle3;
 71                len++;
 72                ang[ len ].angle1 = angle4;
 73                ang[ len ].angle2 = angle2;
 74                len++;
 75             }

 76            else
 77            {
 78                ang[ len ].angle1 = angle1;
 79                ang[ len ].angle2 = angle2;
 80                len++;
 81            }

 82
 83        }

 84        sort( ang, ang + len, cmp );
 85        double st = ang[ 0 ].angle1, ed = ang[ 0 ].angle2;
 86        int ans = 1, cnt = 0;
 87        forint i = 1; i < len; i++ )
 88        {
 89            if( D( ang[ i ].angle1 - ed ) > 0 )
 90            {
 91                if( cnt > ans ) ans = cnt;
 92                st = ang[ i ].angle1, ed =ang[ i ].angle2;
 93            }

 94            else
 95            {
 96                cnt++;
 97            }

 98        }

 99        printf("%d\n",ans);
100    }

101    return 0;
102}

103