/** @Cain*/
const int maxn = 1e5+5;
const db eps = 1e-7;
int a[maxn],b[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
db l = 0, r = inf , mid;
while(r - l > eps){
mid = (r+l)/2.0;
db maxx = -inf, minn = inf;
for(int i=1;i<=n;i++){
db xl = a[i]*1.0 - b[i]*mid;
db xr = a[i]*1.0 + b[i]*mid;
maxx = max(maxx,xl); //千万不要找错了,是找最小的进
//行比较, 而不是最大的, 既是往左和右移动距离小的那两个.
//如果直接找最大的两个点则有可能有交叉部分.
minn = min(minn,xr);
}
if(fabs(maxx - minn) < eps)
break;
else if(maxx < minn) r = mid;
else l = mid;
}
printf("%.12lf\n",mid);
}
HDU 4717 传送门
//思路:在平面中任意两个点的距离一定是先减小, 后增大的, 不信可以画出来看一看. 所以满足单峰函数, 所以就可以用三分来做.
/** @Cain*/
const int maxn = 3e2+5;
const db eps = 1e-6;
int x[maxn],y[maxn],vx[maxn],vy[maxn];
int n;
int cas = 1;
db cal(db t)
{
db res = 0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
db x1 = x[i]*1.0+vx[i]*t;
db y1 = y[i]*1.0+vy[i]*t;
db x2 = x[j]*1.0+vx[j]*t;
db y2 = y[j]*1.0+vy[j]*t;
db maxx = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
res = max(maxx,res);
}
}
return res;
}
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x[i],&y[i],&vx[i],&vy[i]);
}
db l = 0, r = inf,len;
db lm,rm;
while(r - l > eps){
len = (r-l)/3.0;
lm = l + len;
rm = r - len;
db dislm = cal(lm);
db disrm = cal(rm);
if(dislm < disrm) r = rm;
else l = lm;
}
printf("Case #%d: %.2f %.2f\n",cas++,l,cal(l));
}