ACM-ICPC 2012 Regionals Asia - Jinhua D Crazy Tank / HDU 4445
扫描线
http://acm.hdu.edu.cn/showproblem.php?pid=4445
很多人是水过的,我贴个正经的扫描线的吧。
#include <cassert> #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; const double PI = acos(-1.0); const double EPS = 1e-8; inline int sgn(double x) { if (fabs(x)<EPS) return 0; return x>0?1:-1; } int N, M; double l1, r1, l2, r2; double v[222]; double g=9.8, h; double calc(double v, double a) { double vx = v*cos(a); double vy = v*sin(a); double delta = vy*vy+2*g*h; delta = max(0.0, delta); double t = (vy+sqrt(delta))/g; return vx*t; } double tri(double l, double r, double v, double &d) { int cnt = 100; while (cnt--) { double m1 = (l+r)/2; double m2 = (m1+r)/2; if (calc(v, m1)>calc(v, m2)) r = m2; else l = m1; } d = calc(v, l); return l; } double bin(double l, double r, double d, double v, bool up) { int cnt = 100; while (cnt--) { double m = (l+r)/2; if ((calc(v, m)<d)^up) l = m; else r = m; } return l; } struct se { double a; bool in; int cnt; se() {} se(double x, bool y, int z): a(x), in(y), cnt(z) {} bool operator<(const se &rhs) const { if (sgn(a-rhs.a)==0) { return in<rhs.in; } return a<rhs.a; } }e[9999]; void ae(double a, bool in, int cnt) { e[M++] = se(a, in, cnt); } void solve(double l, double r, double d, double v, double t, int cnt) { if (sgn(d-l)<0) return; if (sgn(d-r)<0) { double hmr = bin(-PI/2, t, l, v, 0); double mdk = bin(t, PI/2, l, v, 1); if (sgn(hmr-mdk)>0) while (1) puts(""); ae(hmr, 0, cnt); ae(mdk, 1, -cnt); return; } double s1 = bin(-PI/2, t, l, v, 0); double t1 = bin(-PI/2, t, r, v, 0); double s2 = bin(t, PI/2, r, v, 1); double t2 = bin(t, PI/2, l, v, 1); if (sgn(s1-t1)>0) while (1) puts(""); if (sgn(s2-t2)>0) while (1) puts(""); if (sgn(t1-s2)>=0) { ae(s1, 0, cnt); ae(t2, 1, -cnt); } else { ae(s1, 0, cnt); ae(t1, 1, -cnt); ae(s2, 0, cnt); ae(t2, 1, -cnt); } } char s[111]; int main() { int i, j, k; while (cin>>N>>h>>l1>>r1>>l2>>r2, N) { M = 0; for (i = 0; i < N; ++i) { cin>>v[i]; double d, t; t = tri(-PI/2, PI/2, v[i], d); solve(l1, r1, d, v[i], t, 1); solve(l2, r2, d, v[i], t, -998); } sort(e, e+M); int ans = 0; int cnt = 0; for (i = 0; i < M; ++i) { cnt += e[i].cnt; if (cnt>N) while (1) puts(""); ans = max(ans, cnt); } printf("%d\n", ans); } return 0; }