1 /*
2 求出一个上图像和一个下图像,中间既不是最大值
3 图像的交点,又不是最小值直线的交点,可以扔掉。
4 斜率大的(速度大的),肯定最终到上面。所以我们按
5 斜率进行排序,排序后插入图像(从小到大),将属于
6 自己的位置求出,同理,下图像也可以求出。让上图
7 像和下图像不断移动,即可求出。
8 相当于单调栈。(右图中没有画圈的交点可以扔掉。)
9 这道题一开始保证跑的慢的豹子一定先跑,跑的快的
10 豹子一定后跑。
11 我们只需要记录最上方那条线和最下方那条线
12 被哪个豹子保管。
13 用 f[i]表示第 i 只豹子保管了哪个区间。
14 */
15 #include<cstdio>
16 #include<cstring>
17 #include<cstdlib>
18 #include<cmath>
19 #include<iostream>
20 #include<algorithm>
21
22 using namespace std;
23 const long double INF=(long double)1000000000*10;
24 long double L,R,mid,ans,hh[100005];
25 int r,rr,i,n,MAX,X,Y,cnt,vv[100005],vv2[100005];
26 struct node2 {int t; long double l;} s[200005],S[200005];
27 struct node {int t,v;} t[100005];
28 int cmp(node i,node j) {return i.v<j.v || i.v==j.v && i.t>j.t;}
29 struct Node {long double x;int y,z;} p[200005];
30 int CMP(Node i,Node j) {return i.x<j.x;}
31 long double work(int x,long double y) {return (long double)t[x].v*y-hh[x];}
32 int main()
33 {
34 freopen("chase.in","r",stdin);
35 freopen("chase.out","w",stdout);
36 while (1)
37 {
38 scanf("%d",&n);
39 // if (n==0) return 0;
40 MAX=0;
41 for (i=1; i<=n; i++)
42 {
43 scanf("%d%d",&t[i].t,&t[i].v);
44 MAX=max(MAX,t[i].t);
45 }
46 sort(t+1,t+n+1,cmp); int MIN=t[n].t;
47 for (i=n-1; i>=2; i--)
48 {
49 if (t[i].t>MIN) vv[i]=1; else
50 MIN=t[i].t,vv[i]=0;
51 }
52 for (i=1; i<=n; i++) hh[i]=(long double)t[i].t*t[i].v;
53 r=1; s[1].l=MAX; s[1].t=1; s[2].l=INF; vv[n]=0;
54 for (i=2; i<=n; i++)
55 if (!vv[i])
56 {
57 while (r && work(i,s[r].l)>=work(s[r].t,s[r].l)) r--;
58 if (!r) {r=1; s[1].l=MAX; s[1].t=i; continue;}
59 L=s[r].l; R=s[r+1].l; mid=(L+R)/2.0;
60 for (int I=1; I<=80; I++)
61 {
62 if (work(i,mid)>=work(s[r].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
63 }
64 s[++r].l=mid; s[r].t=i; s[r+1].l=INF;
65 }
66 rr=1; S[1].l=MAX; S[2].l=INF; S[1].t=n;
67 MIN=t[1].t;
68 for (i=2; i<n; i++)
69 if (t[i].t<MIN) vv2[i]=1; else
70 MIN=t[i].t,vv2[i]=0;
71 for (i=n-1; i>=1; i--)
72 if (!vv2[i])
73 {
74 while (rr && work(i,S[rr].l)<=work(S[rr].t,S[rr].l)) rr--;
75 if (!rr) {rr=1; S[1].l=MAX; S[1].t=i; continue;}
76 L=S[rr].l; R=S[rr+1].l; mid=(L+R)/2.0;
77 for (int I=1; I<=80; I++)
78 {
79 if (work(i,mid)<=work(S[rr].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
80 }
81 S[++rr].l=mid; S[rr].t=i; S[rr+1].l=INF;
82 }
83 cnt=0;
84 for (i=1; i<=r; i++) {p[++cnt].x=s[i].l; p[cnt].y=1; p[cnt].z=s[i].t;}
85 for (i=1; i<=rr; i++) {p[++cnt].x=S[i].l; p[cnt].y=0; p[cnt].z=S[i].t;}
86 sort(p+1,p+cnt+1,CMP); X=Y=0; ans=INF;
87 for (i=1; i<=cnt; i++)
88 {
89 if (p[i].y==1) X=p[i].z; else Y=p[i].z;
90 // printf("%.5f
",(double)p[i].x);
91 if (X && Y) ans=min(ans,work(X,p[i].x)-work(Y,p[i].x));
92 }
93 printf("%.2f
",fabs((double)ans));
94 return 0;
95 }
96 }