照着《挑战程序设计竞赛》敲的,不知道为什么WA,先把代码贴在这里,以后再说。
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#include<cmath>
using namespace std;
double EPS=1e-10;
#define maxn 55
#define min(a,b) (a<b)?a:b
const double g=9.8;
int N,V,X,Y;
int L[maxn],B[maxn],R[maxn],T[maxn];
//计算以vy的竖直向上射出t秒后的位置
double calc(double vy,double t)
{
return vy*t-g*t*t/2;
}
//a相对lb和ub的位置
int cmp(double lb,double ub,double a)
{
return a<lb+EPS?-1:a>ub-EPS?1:0;
}
//判断当射出路径过点(qx,qy)时,卵能否集中猪
bool check(double qx,double qy)
{
//设初速度在x方向上和y方向上的分量分别是vx,vy,设通过(qx,qy)的时间是t
//求解联立方程vx^2+vy^2=V^2,vx*t=qx,vy*t-g*t*t/2=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 false;
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,X/vx);
if(yt<Y-EPS) continue;
bool ok=true;
for(int i=0;i<N;i++){
if(L[i]>=X) continue;
//判断在猪正上方的鸟和猪之间是否有障碍物
if(R[i]==X&&Y<=T[i]&&B[i]<=yt) ok=false;
//判断在飞到猪上方之前是否会撞到障碍物
int yL=cmp(B[i],T[i],calc(vy,L[i]/vx));//左侧的相对位置
int yR=cmp(B[i],T[i],calc(vy,R[i]/vx));//右侧的相对位置
int xH=cmp(L[i],R[i],vx*(vy/g));//最高点的相对位置
int yH=cmp(B[i],T[i],calc(vy,vy/g));
if(xH==0&&yH>=0&&yL<0) ok=false;
if(yL*yR<=0) ok=false;
}
if(ok) return true;
}
return false;
}
void solve()
{
//截掉猪以右的障碍物
for(int i=0;i<N;i++){
R[i]=min(R[i],X);
}
bool ok=check(X,Y);//直接撞上猪的情况
for(int i=0;i<N;i++){
ok|=check(L[i],T[i]);//经过左上角的情况
ok|=check(R[i],T[i]);//经过右上角的情况
}
puts(ok?"YES":"NO");
}
int main()
{
while(scanf("%d%d%d%d",&N,&V,&X,&Y)!=EOF){
for(int i=0;i<N;i++){
scanf("%d%d%d%d",&L[i],&B[i],&R[i],&T[i]);
}
solve();
}
return 0;
}