AOJ2308 White Bird

来源:互联网 发布:php实例化对象的方法 编辑:程序博客网 时间:2024/05/04 19:09

计算几何,自己不会,全照抄的,找不到原题链接了,也不知道写对了没有

#include<stdio.h>#include<string>#include<math.h>#define MAX_N 100const 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返回1return 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=qxvy*t-1/2gt^2=qydouble a=g*g/4,b=g*qy-V*V,c=qx*qx+qy*qy;//联立方程组而得double D=b*b-4*a*c;//detif (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^2if (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_JUDGEfreopen("in.txt","r",stdin);#endifwhile(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;}

0 0
原创粉丝点击