HDU 4458 Shoot the Airplane(计算几何or数学)
2016-07-23 21:07
447 查看
思路:固定飞机不动,那么相当于子弹多了一个水平速度-v,那么就可以将子弹的轨迹看作一条抛物线,枚举抛物线上的点然后判点是否在多边形内即可
#include<bits/stdc++.h>
using namespace std;
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!");
}
}
Description
XXX is playing an interesting game which is based on a 2D plane. In this game, he is required to shoot an airplane. The airplane flies horizontally. The shape of it can be regarded as a simple polygon. Player has to shoot at point
(0, 0) upward vertically. Because the bullet is very small, it can be regarded as a point. The airplane is hit only if the bullet goes into the airplane. The airplane is not hit if the bullet only touches the edge of the airplane. The gravity should be considered.
The acceleration of gravity is g and its direction is downward vertically. So the speed of the bullet may be change during flying. But the speed of airplane is constant because it has engines. XXX wants to know the time it takes the bullet to hit the airplane
after shooting.
Input
There are multiple cases.
In each case, there are three integers v (-10<= v <= 10), b (1 <= b <= 10), g (0 <= g <= 10) in the first line. v denotes the speed of airplane. The flying direction is from left to right if v is positive and the direction is from right to left if v is negative.
b denotes the initial speed of bullet. g is the acceleration of gravity. Then the input will describe the position of the airplane when XXX shoots. In the second line, there is one integer n (3 <= n <= 20) which represents the number of vertexes of the airplane
(polygon). In each of the next n lines, there are two integers x (-100 <= x <= 100), y (0 <y<= 100) which give the position of a vertex in order. There is a blank line after each case. The input ends with 0 0 0.
Output
If the airplane is hit, then output the time it takes the bullet to hit it after shooting in one line. The answer should be rounded to 2 digits after decimal point. If the airplane is not hit, then output “Miss!” in one line.
Sample Input
-10 10 2
9
6 9
10 9
10 16
25 16
25 20
10 20
10 27
6 27
-10 18
-10 10 2
9
6 9
10 9
10 16
20 16
20 20
10 20
10 27
6 27
-10 18
0 0 0
Sample Output
2.00
Miss!
#include<bits/stdc++.h>
using namespace std;
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!");
}
}
Description
XXX is playing an interesting game which is based on a 2D plane. In this game, he is required to shoot an airplane. The airplane flies horizontally. The shape of it can be regarded as a simple polygon. Player has to shoot at point
(0, 0) upward vertically. Because the bullet is very small, it can be regarded as a point. The airplane is hit only if the bullet goes into the airplane. The airplane is not hit if the bullet only touches the edge of the airplane. The gravity should be considered.
The acceleration of gravity is g and its direction is downward vertically. So the speed of the bullet may be change during flying. But the speed of airplane is constant because it has engines. XXX wants to know the time it takes the bullet to hit the airplane
after shooting.
Input
There are multiple cases.
In each case, there are three integers v (-10<= v <= 10), b (1 <= b <= 10), g (0 <= g <= 10) in the first line. v denotes the speed of airplane. The flying direction is from left to right if v is positive and the direction is from right to left if v is negative.
b denotes the initial speed of bullet. g is the acceleration of gravity. Then the input will describe the position of the airplane when XXX shoots. In the second line, there is one integer n (3 <= n <= 20) which represents the number of vertexes of the airplane
(polygon). In each of the next n lines, there are two integers x (-100 <= x <= 100), y (0 <y<= 100) which give the position of a vertex in order. There is a blank line after each case. The input ends with 0 0 0.
Output
If the airplane is hit, then output the time it takes the bullet to hit it after shooting in one line. The answer should be rounded to 2 digits after decimal point. If the airplane is not hit, then output “Miss!” in one line.
Sample Input
-10 10 2
9
6 9
10 9
10 16
25 16
25 20
10 20
10 27
6 27
-10 18
-10 10 2
9
6 9
10 9
10 16
20 16
20 20
10 20
10 27
6 27
-10 18
0 0 0
Sample Output
2.00
Miss!
相关文章推荐
- HDU 4460 Friend Chains(最短路)
- rails 做api接口入门说明
- Tree Traversals Again
- POJ1995 Raising Modulo Numbers
- 【bzoj4320】ShangHai2006 Homework
- HDU - 5319 Painter
- [Rails]route.rb理解积累
- 使用flash air开发应用
- Cassandra User 问题汇总(1)------------repair
- Cassandra User 问题汇总(1)------------repair
- 【HDU】-1789-Doing Homework again(贪心,好)
- 219. Contains Duplicate II
- NSSearchPathForDirectoriesInDomains用法--转自平静大海
- 217. Contains Duplicate
- HDOJ 1789 Doing Homework again
- HDOJ 2124 Repair the Wall(修城墙,贪心)
- POJ 1995 Raising Modulo Numbers
- HDU Problem - 1789 Doing Homework again【贪心】
- poj 1995 Raising Modulo Numbers
- Doing Homework again(贪心)