计算几何,自己不会,全照抄的,找不到原题链接了,也不知道写对了没有
#include<stdio.h>
#include<string>
#include<math.h>
#define MAX_N 100
const double EPS=1e-8;
const double g=9.8; //重力加速度
//输入
int N,V,X,Y;
int L[MAX_N],B[MAX_N],R[MAX_N],T[MAX_N];
double min(double a,double b) {
return a<b?a:b;
}
//计算以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) { //a<lb,返回-1, lb<a<ub,返回0 ,ub<a返回1
return a<lb+EPS?-1:a>ub-EPS?1:0;
}
//判断当射出路径经过点(qx,qy)时,卵是否能击中猪
bool check (double qx,double qy) {
//初速度分量vx,vy,设通过(qx,qy)的时间为t
//求解联立方程式vx^2+vy^2=V^2 vx*t=qx vy*t-1/2gt^2=qy
double a=g*g/4,b=g*qy-V*V,c=qx*qx+qy*qy; //联立方程组而得
double D=b*b-4*a*c; //det
if (D<0 && D>-EPS) D=0;
if (D<0) return false;
int d;
for(d=-1;d<=1;d+=2) { //验证联立方程式的两个解的循环
double t2=(-b+d*sqrt(D)) /(2*a); //t2 为t^2
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;
int i;
for(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() {
//截掉猪以右的障碍物
int i;
for(i=0;i<N;i++) {
R[i]=min(R[i],X);
}
bool ok=check(X,Y); //直接撞上猪的情况
for(i=0;i<N;i++) {
ok|=check(L[i],T[i]); //经过左上角的情况
ok|=check(R[i],T[i]); //经过右上角的情况
}
puts(ok?"Yes":"No");
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(scanf("%d%d%d%d",&N,&V,&X,&Y)!=EOF) {;
int i;
for(i=0;i<N;i++) {
scanf("%d%d%d%d",&L[i],&B[i],&R[i],&T[i]);
}
solve();
}
return 0;
}