zoukankan      html  css  js  c++  java
  • HDU 4458 Shoot the Airplane(计算几何 判断点是否在n边形内)

    Shoot the Airplane

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


    Problem 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!
     
    Source

    题目大意:

      题目的意思就是说,给你一个二维平面图,然后,在(0,0)点有一个发射炮,有一个n边形的飞机,问你有没有可能这个炮弹打到飞机。飞机以v=v0做匀速运动,炮弹是具有初速度为b,重力加速度为g的上抛运动。。。。如果能够打到飞机的话,就输出在某一个时刻

    解题思路:

      这道题当时现场赛A出来的人不多,有可能是因为精度问题吧,但是,说实话,这个题的难度并不大,如果考虑到了相对坐标变化的思想,就很容易能够写出来了,

    我们假设飞机静止不动,那么,这个导弹的飞行曲线就是一个类似于 平抛运动的物体了x=-v*t,y=0.5*g*t*t;

    有关点在多边形内部的判断用的是LRJ的模板。

    代码:

    # include<cstdio>
    # include<iostream>
    # include<vector>
    # include<cmath>
    
    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;
    }
    
    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;
    }
    
    int main(void)
    {
        int n;
        double v,b,g;
    
        while( scanf("%lf%lf%lf",&v,&b,&g)!=EOF )
        {
            if(v==0&&b==0&&g==0)
                break;
            scanf("%d",&n);
            Polygon p;
            double max_y = 0.0,x,y;
            for( int i = 0;i < n;i++ )
            {
                scanf("%lf%lf",&x,&y);
                max_y =max(max_y,y);
                p.push_back(Point(x,y));
            }
            int ok=0;
            double T=dcmp(g)?2.0*b/g:max_y/b;
            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
    ",t);
                    ok=1;
                    break;
                }
            }
            if(!ok)
                puts("Miss!");
        }
    }
    

      

  • 相关阅读:
    Windows 编程入门,了解什么是UWP应用。
    java getway springcloud 记录请求数据
    nginx服务器配置传递给下一层的信息的一些参数-设置哪些跨域的域名可访问
    e.printStackTrace() 原理的分析
    关于性能测试组出现的问题查询和优化
    springboot connecting to :mongodb://127.0..0.1:27017/test authentication failed
    redis 集群 slots are covered by nodes.
    @PostConstruct +getapplicationcontext.getbean springboot获取getBean
    idea 错误: 找不到或无法加载主类 xx.xxx.Application
    elastic-job和spring cloud版本冲突2
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4772073.html
Copyright © 2011-2022 走看看