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
)
(X, Y)
(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.8
m
/
s
2
.
9.8 {\rm m/s^2}.
9.8m/s2. Gravity exerts a force on the objects in the decreasing direction of
y
y
y-coordinate.
Input
A dataset follows the format shown below:
N
V
X
Y
N\ V\ X\ Y
N V X Y
L
1
B
1
R
1
T
1
L_1 B_1 R_1 T_1
L1B1R1T1
.
.
.
...
...
L
N
B
N
R
N
T
N
L_N B_N R_N T_N
LNBNRNTN
All inputs are integer.
N
N
N: the number of obstacles
V
V
V: the initial speed of the white bird
X
,
Y
X, Y
X,Y: the position of the pig
(
0
≤
N
≤
50
,
0
≤
V
≤
50
,
0
≤
X
,
Y
≤
300
,
X
≤
0
)
(0 \leq N \leq 50, 0 \leq V \leq 50, 0 \leq X, Y \leq 300, X \leq 0)
(0≤N≤50,0≤V≤50,0≤X,Y≤300,X≤0)
for 1 ≤ i ≤ N 1 \leq i \leq N 1≤i≤N,
L
i
L_i
Li: the
x
x
x-coordinate of the left side of the
i
i
i-th obstacle
B
i
B_i
Bi: the
y
y
y-coordinate of the bottom side of the
i
i
i-th obstacle
R
i
R_i
Ri: the
x
x
x-coordinate of the right side of the $i4-th obstacle
T
i
T_i
Ti: the $y4-coordinate of the top side of the
i
i
i-th obstacle
(
0
≤
L
i
,
B
i
,
R
i
,
T
i
≤
300
)
(0 \leq L_i, B_i, R_i, T_i \leq 300)
(0≤Li,Bi,Ri,Ti≤300)
It is guaranteed that the answer remains unaffected by a change of L i , B i , R i L_i, B_i, R_i Li,Bi,Ri and T i T_i Ti in 1 0 − 6 . 10^{-6}. 10−6.
Output
Y
e
s
/
N
o
Yes/No
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 N N个长方形的障碍物,小鸟从 ( 0 , 0 ) (0,0) (0,0)处以大小为 V V V的速度射出,问能否下蛋砸中位于 ( X , Y ) (X,Y) (X,Y)处的猪
题解
- 可以枚举小鸟经过每一个长方形的四个顶点,如果这时能砸中,则答案为 Y e s Yes Yes
- 原因是假设不经过任何长方形的任何顶点,总可以通过调整使得经过某个长方形的顶点使得轨迹经过某个顶点
- 简单说一下小鸟会不会撞上某个长方形的方法:可以算出经过长方形左边界时的位置与长方形上下边界的关系,然后算出从右边界射出的位置来判定会不会撞上
- 当然需要注意 / 0 /0 /0的情况,好像这题不需要太注意精度
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
const double g=9.8;
const double eps=1e-8;
double lx[maxn],ly[maxn],rx[maxn],ry[maxn],x,y,v;
int n;
int sgn(double k)
{
return k<-eps?-1:(k<eps?0:1);
}
double calc(double vv,double t)
{
return vv*t-g*t*t/2;
}
bool check(double ex,double ey)
{
double a=4*ex*ex+4*ey*ey,b=4*ey*ex*ex*g-4*ex*ex*v*v,c=g*g*ex*ex*ex*ex;
double vx,vy,vx2;
double k=b*b-4*a*c;
k+=eps;
if(k<0) return false;
for(int d=-1;d<=1;d+=2) {
vx2=(-b+d*sqrt(k))/(2*a);
vx2+=eps;
if(vx2<=0) continue;
vx=sqrt(vx2);vy=sqrt(v*v-vx*vx);
bool ok=true;
double ty=calc(vy,x/vx);
if(sgn(ty-y)<0) continue;
for(int i=1;i<=n;i++) {
if(sgn(lx[i]-x)>=0) continue;
if(sgn(rx[i]-x)>=0&&sgn(lx[i]-x)<=0&&sgn(ly[i]-ty)<0&&sgn(ry[i]-y)>0) ok=false;
double zuoy=calc(vy,lx[i]/vx),youy=calc(vy,min(rx[i],x)/vx),topy=vy*vy/(2*g);
if(sgn(zuoy-ly[i])<=0) {
if(sgn(ly[i]-youy)<0) ok=false;
else if(sgn(topy-ly[i])>0&&sgn(vx*(vy/g)-min(rx[i],x))<0&&sgn(vx*(vy/g)-lx[i])>0) ok=false;
}
else if(sgn(zuoy-ly[i])>0&&sgn(zuoy-ry[i])<0) ok=false;
else{
if(sgn(youy-ry[i])<0) ok=false;
}
}
if(ok) return true;
}
return false;
}
int main()
{
scanf("%d %lf %lf %lf",&n,&v,&x,&y);
for(int i=1;i<=n;i++) scanf("%lf %lf %lf %lf",&lx[i],&ly[i],&rx[i],&ry[i]);
if(check(x,y)) return printf("Yes\n"),0;
for(int i=1;i<=n;i++) {
if(check(lx[i],ly[i])) return printf("Yes\n"),0;
if(check(lx[i],ry[i])) return printf("Yes\n"),0;
if(check(rx[i],ly[i])) return printf("Yes\n"),0;
if(check(rx[i],ry[i])) return printf("Yes\n"),0;
}
printf("No\n");
}