题目大意:
就是现在给定炮台高度H, 友军坦克区间[L2, R2], 敌军坦克区间[L1, R1], 现在又N发炮弹以各自的速度从炮台出射出, 可以自由调整炮台角度但是所有炮弹的角度必须一致
问在没有炮弹掉进友军坦克所在区间的条件下击中敌军坦克区间的炮弹做多能有多少个
大致思路:
刚开始想的是枚举哪个炮弹击中区间的某个边缘然后计算角度, 然后发现计算量很大, 而且精度可能有问题, 后来发现枚举角度是一个很不错的选择, 将角度分成1000份, 由于炮弹只有200个, 一次判断每个炮弹的落点即可
代码如下:
Result : Accepted Memory : 1632 KB Time : 246 ms
/* * Author: Gatevin * Created Time: 2015/3/18 12:27:32 * File Name: Kotori_Itsuka.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; int n; double v[220]; double H, L1, R1, L2, R2; const double PI = acos(-1.0); const double g = 9.8; int count(double angle) { double vx, vy; double ret = 0; if(angle > PI/2) { angle -= PI/2; for(int i = 0; i < n; i++) { vx = v[i]*cos(angle); vy = v[i]*sin(angle); double t = (sqrt(2*g*H + vy*vy) + vy)/g; double x = vx*t; if(x >= L2 && x <= R2) return 0; if(x >= L1 && x <= R1) ret++; } } else { for(int i = 0; i < n; i++) { vx = v[i]*sin(angle); vy = v[i]*cos(angle); double t = (sqrt(2*g*H + vy*vy) - vy)/g; double x = vx*t; if(x >= L2 && x <= R2) return 0; if(x >= L1 && x <= R1) ret++; } } return ret; } int main() { while(scanf("%d", &n), n) { scanf("%lf %lf %lf %lf %lf", &H, &L1, &R1, &L2, &R2); for(int i = 0; i < n; i++) scanf("%lf", v + i); int ans = 0; for(double angle = 0; angle <= PI; angle += PI/1000) ans = max(ans, count(angle)); printf("%d\n", ans); } return 0; }