AOJ2308-White Bird

White Bird

Angry Birds is a mobile game of a big craze all over the world. You were convinced that it was a waste of time to play the game, so you decided to create an automatic solver.

You are describing a routine that optimizes the white bird's strategy to defeat a pig (enemy) by hitting an egg bomb. The white bird follows a parabolic trajectory from the initial position, and it can vertically drop egg bombs on the way.

In order to make it easy to solve, the following conditions hold for the stages.

  • N obstacles are put on the stage.
  • Each obstacle is a rectangle whose sides are parallel to the coordinate axes.
  • The pig is put on the point (X,Y).
  • You can launch the white bird in any direction at an initial velocity V from the origin.
  • If the white bird collides with an obstacle, it becomes unable to drop egg bombs.
  • If the egg bomb collides with an obstacle, the egg bomb is vanished.

The acceleration of gravity is 9.8m⁄s2. Gravity exerts a force on the objects in the decreasing direction of y-coordinate.

Input

A dataset follows the format shown below:

N V X Y
LBRT1

LN BN RN TN

All inputs are integer.

  • N: the number of obstacles
  • V: the initial speed of the white bird
  • XY: the position of the pig

(0≤N≤50, 0≤V≤50, 0≤X,Y≤300, X≠0)

for 1≤iN,

  • Li: the x-coordinate of the left side of the i-th obstacle
  • Bi: the y-coordinate of the bottom side of the i-th obstacle
  • Ri: the x-coordinate of the right side of the i-th obstacle
  • Ti: the y-coordinate of the top side of the i-th obstacle

(0≤Li,Bi,Ri,Ti≤300)

It is guaranteed that the answer remains unaffected by a change of LiBiRi and Ti in 10−6.

Output

Yes/No

You should answer whether the white bird can drop an egg bomb toward the pig.

Sample Input 1

0 7 3 1

Output for the Sample Input 1

Yes

Sample Input 2

1 7 3 1
1 1 2 2

Output for the Sample Input 2

No

Sample Input 3

1 7 2 2
0 1 1 2

Output for the Sample Input 3

No

题意:给n个障碍物和一个猪的位置坐标一个初速度的小鸟,小鸟可以在飞行的过程中任意位置下一个蛋问蛋能否击中猪,小鸟撞到障碍物就会停下;

题解:我们分析不能被砸中的情况

  1. 当小鸟不能飞行到猪的上方在这之前就碰到障碍物了
  2. 当小鸟能飞到猪的正上方

小鸟向上飞行的过程中可以从一个障碍物的左上角飞过也可以从一个障碍物的右下角飞过对于每一种我们都考虑这个极限不断更改小鸟的发射角度然后枚举每一个在猪之前的障碍物判断其是否能击中                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   


#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define rep(a,b) for(int a=0;a<b;a++)
#define pre(a,b) for(int a=b,a>0;a--)
const int maxn=1e8+7;
const int minn=100+7;
const double g=9.8;
const double eps=1e-10;
struct Barr
{
    int l,b,r,t;
} q[minn];
int n,v,ex,ey;
int cmp(Barr a,Barr b)
{
    if(a.l==b.l){return a.b<b.b;}
    return a.l<b.l;
}
//判断t秒后y的位置
double calc(double vy,double t)
{
    return vy*t-g*t*t/2;
}
int judge(double lb,double ub,double a)
{
    return a<lb+eps?-1:a>ub-eps?1:0;
}
int check(double qx,double qy)
{
    double a=g*g/4,b=g*qy-v*v,c=qx*qx+qy*qy;
    double D=b*b-4*a*c;
    if(D<0&&D>-eps)D=0;
    if(D<0)return 0;
    for(int d=-1;d<=1;d+=2){
        double t2=(-b+d*sqrt(D))/(2*a);
        if(t2<=0){continue;}
        double t=sqrt(t2);
        double vx=qx/t,vy=(qy+g*t*t/2)/t;
        double yt=calc(vy,ex/vx);
        if(yt<ey-eps){continue;}
        int ok=1;
        for(int i=0;i<n;i++)
        {
            if(q[i].l>=ex){break;}
            if(q[i].r==ex&&ey<=q[i].t&&q[i].b<=yt)ok=0;
            int yl=judge(q[i].b,q[i].t,calc(vy,q[i].l/vx));
            int yr=judge(q[i].b,q[i].t,calc(vy,q[i].r/vx));
            int xh=judge(q[i].l,q[i].r,vx*(vy/g));
            int yh=judge(q[i].b,q[i].t,calc(vy,vy/g));
            if(xh==0&&yh>=0&&yl<0)ok=0;
            if(yl*yr<=0)ok=0;
        }
        if(ok)return 1;
    }
    return 0;
}
void slove()
{
    sort(q,q+n,cmp);
    int ok=check(ex,ey);//直接撞上的情况
    for(int i=0;i<n;i++)
    {
        if(q[i].l>=ex){break;}
        ok|=check(q[i].l,q[i].t)|check(q[i].r,q[i].t);
    }
    puts(ok?"Yes":"No");
    return ;
}
int main()
{
    scanf("%d%d%d%d",&n,&v,&ex,&ey);
    rep(i,n)
    {
        scanf("%d%d%d%d",&q[i].l,&q[i].b,&q[i].r,&q[i].t);
        q[i].r=min(ex,q[i].r);
    }
    slove();
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值