acdreamer 1221&&sgu204 (三分)
來源:程序員人生 發布時間:2016-06-16 13:52:42 閱讀次數:2836次
題目鏈接:傳送門
題意:給出b1,t1,b2,t2,l,ds,df,和重力加速的g,左側斑點表示出發點,右側斑點表示終點,你可以從出發點以任意角度、任意速度投出1個小球,從t1,b1中穿過去,落在l上,然后再重新在落點以任意角度、任意速度投出這個球然后從t2,b2中間穿過去于終點落地,然后求兩次投擲速度中的最大值的最小值是多少,也就是MIN(MAX(v1,v2))。
分析:首先我們會發現以在l中間的落腳點為自變量,答案是1個單峰函數,存在最小值.
然后這樣我們就能夠3分答案去求落腳點了,但是要注意精度,應當這樣while(high-low>1e⑴2)注意精度
然后就是對兩次投擲分開求最小速度,最重要的是在求解這個拋物線方程。對1次投擲,我們很容易發現45°投出是初速度最小的(實際上是生活常識啊),然后由于投擲是1個拋物線,假定以投擲點為原點,然后以落腳點坐標x0,那末45°的解析式就是 y=⑴/x0*x(x-x0),然后我們判斷以45°投出時是不是會觸碰到上下界,如果觸碰到了,很容易腦補出只需要將角度恰好調劑到上下界的高度,再求解出來拋物線方程就好了。本題拋物線方程采取y=a*x*(x-x0);
代碼以下:
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
const double pi=acos(⑴);
const int maxn=100005;
const int INF=0x3f3f3f;
const double eps=1e⑴2;
int dcmp(double x){
if(fabs(x)<eps)return 0;
if(x>0)return 1;
return ⑴;
}//精度為eps的比較
double b1,t1,b2,t2,l,ds,df,g;
double calu(double dis,double x,double b,double t){
double v=0;
double mid=dis/2;
double a=⑴/dis;
double y=a*x*x+x;
if(y>=b&&y<=t){
double h=a*mid*mid+mid;
double t,vx,vy;
t=sqrt(2*h/g);
vx=dis/t/2;
vy=g*t;
v=vx*vx+vy*vy;
}
else{
if(y<b)
a=b/(x*x-dis*x);
else
a=t/(x*x-dis*x);
double h=a*mid*(mid-dis);
double t,vx,vy;
t=sqrt(2*h/g);
vx=dis/t/2;
vy=g*t;
v=vx*vx+vy*vy;
}
return v;
}
double solve(double t){
double ans1=ds+t;
double ans2=df+l-t;
double v1,v2;
v1=calu(ans1,ds,b1,t1);
v2=calu(ans2,l-t,b2,t2);
return max(v1,v2);
}
int main(){
while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&b1,&t1,&b2,&t2,&l,&ds,&df,&g)!=EOF){
double low,high,mid,midd;
low=0;
high=l;
while(high-low>eps){
mid=(high+low*2)/3;
midd=(low+high*2)/3;
if(solve(mid)<solve(midd))high=midd;
else low=mid;
}
printf("%.4f\n",sqrt(solve(mid)));
}
return 0;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈