标签:
1.题目描述:点击打开链接
2.解题思路:本题利用运动的相对性解决。可以假设飞机固定不动,那么子弹相当于还有一个水平分量,只不过方向是-v。这样,问题就转化为一个动点什么时候到达一个多边形内部的问题了。不过本题有一个细节就是g可能等于0,因此要分匀变速运动和匀速运动2种情况求出最大可能的子弹飞行时间。另外一个细节就是本题对精度要求比较高,建议判断点是否在线段上改为利用坐标的差值来判断,避开使用Dot函数。
3.代码:
#include<iostream> #include<algorithm> #include<cassert> #include<string> #include<sstream> #include<set> #include<bitset> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cctype> #include<functional> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define me(s) memset(s,0,sizeof(s)) #define rep(i,n) for(int i=0;i<(n);i++) typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; //typedef pair <int, int> P; const double PI=acos(-1.0); const double eps=1e-10; int dcmp(double x) { if(fabs(x)<eps)return 0; return x<0?-1:1; } struct Point { double x,y; Point(){} Point(double x,double y):x(x),y(y){} Point operator+(const Point&p){return Point(x+p.x,y+p.y);} Point operator-(const Point&p){return Point(x-p.x,y-p.y);} Point operator*(double p){return Point(x*p,y*p);} Point operator/(double p){return Point(x/p,y/p);} }; typedef Point Vector; double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;} double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} double Length(Vector a){return sqrt(Dot(a,a));} double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));} bool OnSegment(Point p,Point a,Point b) { if(dcmp(Cross(p-a,p-b)))return 0; return dcmp(a.x-p.x)*dcmp(b.x-p.x)<=0&&dcmp(a.y-p.y)*dcmp(b.y-p.y)<=0; //利用dcmp判断,避免使用Dot } typedef vector<Point> Polygon; int isPointInPolygon(Point p,Polygon poly) { int wn=0; int n=poly.size(); for(int i=0;i<n;i++) { if(OnSegment(p,poly[i],poly[(i+1)%n]))return 0; int k=dcmp(Cross(poly[(i+1)%n]-poly[i],p-poly[i])); int d1=dcmp(poly[i].y-p.y); int d2=dcmp(poly[(i+1)%n].y-p.y); if(k>0&&d1<=0&&d2>0)wn++; if(k<0&&d2<=0&&d1>0)wn--; } return wn; } double v,b,g; int n; int main() { while(~scanf("%lf%lf%lf",&v,&b,&g)) { if(v==0&&b==0&&g==0)break; scanf("%d",&n); Polygon p; double my=0.0,x,y; for(int i=0;i<n;i++) { scanf("%lf%lf",&x,&y); my=max(my,y); p.push_back(Point(x,y)); } int ok=0; double T=dcmp(g)?2.0*b/g:my/b; //分2种情况 for(double t=0.0;t<=T;t+=0.001) { Point tmp(-v*t,b*t-0.5*g*t*t); if(isPointInPolygon(tmp,p)) { printf("%.2lf\n",t); ok=1; break; } } if(!ok)puts("Miss!"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 4458 Shoot the Airplane (2012年杭州赛区现场赛F题)
标签:
原文地址:http://blog.csdn.net/u014800748/article/details/48108689