一. 题目编号
1005
Turn the corner
Problem Description
Mr. West bought a new car! So he is travelling around the city.
One day he comes to a vertical corner. The street he is currently in has a width x, the street he wants to turn to has a width y. The car has a length l and a width d.
Can Mr. West go across the corner?
Input
Every line has four real numbers, x, y, l and w.
Proceed to the end of file.
Output
If he can go across the corner, print “yes”. Print “no” otherwise.
Sample Input
10 6 13.5 4
10 6 14.5 4
Sample Output
yes
no
Source
2008 Asia Harbin Regional Contest Online
二.简单题意
Mr. West驾车来到了一个垂直的角落。Mr. West想通过此弯道,现在给出车子的长和宽,以及直角弯道的宽度和他现在没转弯之前的街道宽度。求出他能不能通过该弯道。
三、解题思路形成过程
要使汽车能转过此弯道,那么就是汽车的左边尽量贴着那个直角点,而汽车的右下后方的点尽量贴着最下面的边。给定X, Y, l, d判断是否能够拐弯。首先当X或者Y小于d,那么一定不能。 其次我们发现随着角度θ的增大,最大高度h先增长后减小,即为凸性函数,可以用三分法来求解。
s = l * cos(θ) + w * sin(θ) - x;
h = s * tan(θ) + w * cos(θ);
其中s为汽车最右边的点离拐角的水平距离, h为里拐点最高的距离, θ范围从0到90。
四、感想
必须得把题目构建为数学模型来解决,
五、AC代码
#include <iostream>
#include <cmath>
using namespace std;
double p= acos(-1.0);
double x,y,l,w,s,h;
double calculate(double a)
{
s = l*cos(a)+w*sin(a)-x;
h = s*tan(a)+w*cos(a);
return h;
}
int main()
{
double min,max,mid,midmid;
while(cin>>x>>y>>l>>w)
{
min = 0.0;
max = p/2;
while(fabs(max-min)>1e-8)
{
mid = (min+max)/2;
midmid = (mid+max)/2;
if(calculate(mid)>=calculate(midmid))max = midmid;
else min = mid;
}
if(calculate(mid)<=y)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}