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>
9
using namespace std;
10
11
const int maxn = 20005;
12
const double eps = 1e-8;
13
const double inf = 1e20;
14
const double pi = acos( -1.0 );
15
const double g = 10.0;
16
17
struct node
18

{
19
double angle1, angle2;
20
}ang[ maxn << 1 ];
21
22
int D( double x )
{ return ( x < -eps ? -1 : x > eps ); }
23
24
bool 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
34
int 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
for( int 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 = ( -b - t ) / 2.0 / a ;
56
angle2 = ( -b + 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 = ( -b - t ) / 2.0 / a ;
68
angle4 = ( -b + 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
for( int 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