链接:传送门
题意:这个游戏是一个2D打飞机游戏,飞机以速度 v 水平飞行,它是一个简单的多边形,玩家从( 0 , 0 )向上射击,子弹有一个出速度 b ,子弹可以看作一个点,打中飞机边缘是无法击落飞机的,只有子弹进入飞机内部才能击落飞机,子弹受重力的影响,给出重力加速度 g ,XXX想知道子弹在第几秒击中飞机,如果始终无法击中则输出 Miss!
- 注意:
- v 有正有负,v > 0 飞机是从左向右,v < 0 飞机从右向左
- g 的范围是 [ 0 , 10 ],如果 g = 0,说明轨迹是一个直线
思路:如果同时考虑子弹的轨迹和飞机的轨迹是非常复杂的,所以让飞机“静止”,这样子弹就有了一个水平方向的速度分量 -v ,子弹的轨迹就变成了一条抛物线,所以只需要枚举判断抛物线上的点是否在“飞机”内就可以了。
balabala:这道题加了点物理知识还是很有趣的,但也是简单题,我用的是扫描法......
/*************************************************************************> File Name: hdu4458.cpp> Author: WArobot > Blog: http://www.cnblogs.com/WArobot/ > Created Time: 2017年05月02日 星期二 02时54分27秒************************************************************************/#include
using namespace std;#define eps 1.0e-10
#define dou doublestruct point{dou x;dou y;
}po[111];int n,m;
dou dabs(dou x){return x<0?-x:x;
}
int dcmp(dou x){if(fabs(x)=min(p1.x,p2.x) && p.y<=max(p1.y,p2.y) && p.y>=min(p1.y,p2.y) ){if ( dabs( (p.x-p1.x)*(p2.y-p1.y) - (p.y-p1.y)*(p2.x-p1.x) )<=eps )return true;}return false;
}
bool inside(point p){int cnt = 0 ;dou xinter; // 血的教训point p1,p2;p1 = po[0];for(int i=1;i<=n;i++){p2 = po[i%n];if( online(p1,p,p2) ) return false;if( p.x<=max(p1.x,p2.x) && p.y<=max(p1.y,p2.y) && p.y>min(p1.y,p2.y) ){if(p1.y!=p2.y){xinter = (p.y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y) + p1.x; // 理论上的最远距离if(p1.x==p2.x || p.x<=xinter) cnt++;}}p1 = p2;}if(cnt%2==0) return false;else return true;
}int main(){// v是飞机飞行速度,b为子弹初始速度,g为重力加速度int v,b,g;point p;while(~scanf("%d%d%d",&v,&b,&g)){if(v==0 && b==0 && g==0) break;scanf("%d",&n);double Top = 0.0;for(int i=n-1;i>=0;i--){scanf("%lf%lf",&po[i].x,&po[i].y);Top = max(Top,po[i].y);}dou t_max = dcmp(g)? 2*b/g : Top/b;// 枚举时间// x = (-v)*t// y = b*t-1/2*g*t^2bool ok = 0;for(dou t = 0.0 ; t <= t_max ; t += 0.001 ){p.x = (-v)*t;p.y = b*t - 0.5*g*t*t;if( inside(p) ){printf("%.2lf\n",t);ok = 1;break;}}if(!ok) printf("Miss!\n");}return 0;
}