HDU 4445Crazy Tank 2012金华现场赛D题(暴力枚举)

来源:互联网 发布:社科院 工作 知乎 编辑:程序博客网 时间:2024/05/22 08:20

Crazy Tank

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2718    Accepted Submission(s): 483


Problem Description
Crazy Tank was a famous game about ten years ago. Every child liked it. Time flies, children grow up, but the memory of happy childhood will never go.

Now you’re controlling the tank Laotu on a platform which is H meters above the ground. Laotu is so old that you can only choose a shoot angle(all the angle is available) before game start and then any adjusting is not allowed. You need to launch N cannonballs and you know that the i-th cannonball’s initial speed is Vi.
On the right side of Laotu There is an enemy tank on the ground with coordination(L1, R1) and a friendly tank with coordination(L2, R2). A cannonball is considered hitting enemy tank if it lands on the ground between [L1,R1] (two ends are included). As the same reason, it will be considered hitting friendly tank if it lands between [L2, R2]. Laotu's horizontal coordination is 0.
The goal of the game is to maximize the number of cannonballs which hit the enemy tank under the condition that no cannonball hits friendly tank.
The g equals to 9.8.
 

Input
There are multiple test case.
Each test case contains 3 lines.
The first line contains an integer N(0≤N≤200), indicating the number of cannonballs to be launched.
The second line contains 5 float number H(1≤H≤100000), L1, R1(0<L1<R1<100000) and L2, R2(0<L2<R2<100000). Indicating the height of the platform, the enemy tank coordinate and the friendly tank coordinate. Two tanks may overlap.
The third line contains N float number. The i-th number indicates the initial speed of i-th cannonball.
The input ends with N=0.
 

Output
For each test case, you should output an integer in a single line which indicates the max number of cannonballs hit the enemy tank under the condition that no cannonball hits friendly tank.
 

Sample Input
210 10 15 30 3510.020.0210 35 40 2 3010.020.00
 

Sample Output
10
Hint
In the first case one of the best choices is that shoot the cannonballs parallelly to the horizontal line, then the first cannonball lands on 14.3 and the second lands on 28.6.In the second there is no shoot angle to make any cannonball land between [35,40] on the condition that no cannonball lands between [2,30].
 

              题目大意:给你一个处在高度h的坦克,有n发炮弹速度分别为v[1]~v[n].然后给定友军的范围l2~r2,敌军的范围l1~r1.求解调整发射角在不炸到友军的条件下,炸到敌军炮弹数量的最大值。角度一经确定不能更改。
   
          解题思路:当时看到发射角还有速度就需要推公式,不过当时想的三分,但又没有把最大点推出来。不过这个题炮弹只有200发,可以暴力枚举,枚举PI的800份,但是枚举0.003或者更小竟然会WA。。。

          题目地址:Crazy Tank

AC代码:
#include<iostream>#include<cmath>#include<cstdio>using namespace std;int n,ma;double h,v[205],l1,r1,l2,r2;;double PI = acos(-1.0),g = 9.8;//[2vsinx/g+(sqrt(v^2sinx^2+2gh)-vsinx)/g]*vcosx x>0向上//[(sqrt(v^2sinx^2+2gh)-vsinx)/g]*vcosx  x<0向下double cal(double x,double v){     return (sqrt(v*v*sin(x)*sin(x)+2*g*h)-v*sin(x))/g*v*cos(x);}void solve(){     int i;     double mid;     double add=PI/800;     //八百份的话肯定add会大于0.003     //但是枚举add等于0.003却会WA掉。。。     for(mid=-PI/2;mid<=PI/2;mid+=add)     {        int cnt=0;        for(i=0;i<n;i++)        {            double s=cal(mid,v[i]);            if(s>=l2&&s<=r2)   //不能炸到友军            {                 cnt=0;                 break;            }            if(s>=l1&&s<=r1)               cnt++;        }        if(cnt>ma)           ma=cnt;     }}int main(){   int i;   while(scanf("%d",&n)&&n)   {        scanf("%lf%lf%lf%lf%lf",&h,&l1,&r1,&l2,&r2);        for(i=0;i<n;i++)          scanf("%lf",&v[i]);        //向上打和向下打,分类讨论.但是最后公式可以合并        ma=0;        solve();        cout<<ma<<endl;   }   return 0;}


原创粉丝点击