HDU 4458 Shoot the Airplane (2012年杭州赛区现场赛F题)

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!");
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 10:06:23

HDU 4458 Shoot the Airplane (2012年杭州赛区现场赛F题)的相关文章

HDU 4455 Substrings (2012年杭州赛区现场赛C题)

1.题目描述:点击打开链接 2.解题思路:本题利用dp解决.不过这个dp的思路的确比太容易想到.需要观察规律才能发现.我们可以从贡献值的角度考虑.以题目中给的样例来说明这种方法. 通过观察相邻两个w值,我们会发现一个事实:每个大区间都包含了小区间的解(这里的解即原题中的sum值).但是这还不够,观察图上标记为红色的数字,它们可以看做是上一个w值对应的区间多出来的新数字,如果我们可以算出这些红色数字的贡献值,那么我们就能得到当前w下的解.那么该如何计算呢? 继续观察后会发现,每次w增加1,区间个数

HDU 4462 Scaring the Birds (2012年杭州赛区现场赛J题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单模拟题.不过重点还是对于题目细节的理解.容易犯2个理解错误:(1)误以为是每个稻草人有不同的scaring range,实际上scaring range是由不同的vacant intersection决定的,跟稻草人毫无关系.(2)误以为所有点都需要被覆盖,实际上题目要求的是只要所有corn被保护就行,插稻草人的地方本来就是空地,有没有被保护无所谓的.由于题目给的范围非常小,完全可以通过枚举集合来确定哪些位置需要稻草人,如果这些稻草人成功的

HDU 4435 charge-station (2012年天津赛区现场赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用DFS解决.不过本题的解法颇为巧妙,注意到2^0+2^1+...+2^(i-1)<2^i,这就意味着即使在0~i-1都建立加油站,费用也会小于单独在i处建立加油站.这就提示我们,可以一开始全部都建立加油站,然后从大到小依次尝试着删除加油站,如果可以删除,就删除,如果不可以,再添加上.那么该如何判断删除第i处之后是否可行呢?可以利用dfs判断,如果当前访问结点u是建立过加油站的,如果它的邻接点v也是建立了加油站的,且dist(u,v)<=d,那么

HDU 4422 The Little Girl who Picks Mushrooms (2012年成都赛区现场赛C题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单模拟题,然而,自己的方法不对WA了很多次==.最后不得不弃用自己的思路了.首先用-1表示还没有使用过的位置.可以每次枚举3个位置,如果发现这3个位置中没有-1且他们的和不能被1024整除,那么return 0,否则,找到没有被标记的另外2个位置,如果这2个位置其中一个为-1,那么直接返回1024,因为我们已经交了三个袋子了,剩下的袋子中如果又没有确定的,那么一定可以凑成1024.否则,计算这2个位置的和,然后看减去若干次1024后剩下多少,

HDU-4442-Physical Examination (2012年金华赛区现场赛A题)

Physical Examination Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5915    Accepted Submission(s): 1656 Problem Description WANGPENG is a freshman. He is requested to have a physical examinat

hdu 4431 第37届ACM/ICPC 天津赛区现场赛A题 枚举

题意:就是给了13张牌.问增加哪些牌可以胡牌.m是数字,s是条,p是筒,c是数字 胡牌有以下几种情况: 1.一个对子 +  4组 3个相同的牌或者顺子.  只有m.s.p是可以构成顺子的.东西南北这样的牌没有顺子. 2.7个不同的对子. 3.1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c.  这13种牌每种都有,而且仅有这13种牌.肯定是有一种2张.其他的1张. 模拟即可,第一个对子的情况需要枚举 很麻烦的模拟,但是貌似稳银的很需要这题,所以这种难度必须要弄懂,加油

hdu 4438 第37届ACM/ICPC 天津赛区现场赛H题

题意:Alice和Bob两个人去打猎,有两种(只)猎物老虎和狼: 杀死老虎得分x,狼得分y: 如果两个人都选择同样的猎物,则Alice得分的概率是p,则Bob得分的概率是(1-p): 但是Alice事先知道Bob先选老虎的概率是Q,问Alice得分的期望最大值是 求期望 如果先去打老虎,则会有bob先去打狼和bob去打老虎两种情况,期望相加则是alice去打老虎的期望,然后求打狼的期望,比较大小即可 1 #include<cstdio> 2 #include<iostream> 3

HDU 4119 Isabella&#39;s Message (2011年成都赛区现场赛I题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,要求模拟一个解密的过程,练习这么久第一次做模拟题1Y了,内心还是很激动的~.只需要根据题意,记录* 所在的位置即可,然后每次都是先解密,后顺时针旋转90度.把每次解密的信息放到一个vector里,接下来就是连接它们,得到解密后的字符串,在map中查找这些单词是否存在即可.如果都存在,就把这条解密信息放到ans中,最后对ans排序,输出ans[0]就是答案. 3.代码: //#pragma comment(linker, "/STACK:

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 thi