Description
致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。
Input
第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1 ~ yn。
Output
仅包含一个实数,为塔的最小高度,精确到小数点后三位。
Sample Input
【输入样例一】
6
1 2 4 5 6 7
1 2 2 4 2 1
【输入样例二】
4
10 20 49 59
0 10 10 0
Sample Output
【输出样例一】
1.000
【输出样例二】
14.500
【数据规模】
对于60%的数据, N ≤ 60;
对于100%的数据, N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
其实这个范围是可以乱搞的,我O(n^2)乱搞,结果各种细节没注意
首先从别人那里知道了塔的横坐标要么是凸壳上的顶点的横坐标,要么是地图拐点的横坐标
所以只要求出来这些横坐标就行
主要是求凸壳上的顶点
我们枚举一条线与其他线的交点(只与斜率比它大的线做交点,然后取横坐标最小的,这样就不重不漏),但是这个不一定是凸包上的,所以还要判断一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const 2 maxn=310; 3 inf=9999999999999999; 4 eps=1e-7; 5 type 6 node=record 7 x,y:double; 8 end; 9 var 10 a,b,c:array[0..maxn]of node; 11 ans:double; 12 n:longint; 13 14 function min(x,y:double):double; 15 begin 16 if x<y then exit(x); 17 exit(y); 18 end; 19 20 function max(x,y:double):double; 21 begin 22 if x>y then exit(x); 23 exit(y); 24 end; 25 26 procedure init; 27 var 28 i,j:longint; 29 y:double; 30 flag:boolean; 31 begin 32 read(n); 33 for i:=1 to n do 34 read(a[i].x); 35 for i:=1 to n do 36 read(a[i].y); 37 for i:=1 to n-1 do 38 begin 39 b[i].x:=(a[i].y-a[i+1].y)/(a[i].x-a[i+1].x); 40 b[i].y:=a[i].y-a[i].x*b[i].x; 41 end; 42 ans:=inf; 43 for i:=1 to n do 44 begin 45 y:=a[i].y; 46 for j:=1 to n-1 do 47 y:=max(y,a[i].x*b[j].x+b[j].y); 48 ans:=min(ans,y-a[i].y); 49 end; 50 c:=a; 51 for i:=1 to n-1 do 52 begin 53 for j:=1 to n-1 do 54 if b[i].x+eps<b[j].x then 55 begin 56 a[i].x:=(b[j].y-b[i].y)/(b[i].x-b[j].x); 57 a[i].y:=a[i].x*b[i].x+b[i].y; 58 break; 59 end; 60 for j:=1 to n-1 do 61 if b[i].x+eps<b[j].x then 62 if (b[j].y-b[i].y)/(b[i].x-b[j].x)<a[i].x then 63 begin 64 a[i].x:=(b[j].y-b[i].y)/(b[i].x-b[j].x); 65 a[i].y:=a[i].x*b[i].x+b[i].y; 66 end; 67 end; 68 for i:=1 to n-1 do 69 begin 70 flag:=true; 71 for j:=1 to n-1 do 72 if a[i].y+eps<a[i].x*b[j].x+b[j].y then flag:=false; 73 if flag=false then continue; 74 for j:=1 to n-1 do 75 if (c[j].x-eps<a[i].x) and (a[i].x<c[j+1].x+eps) then ans:=min(ans,a[i].y-a[i].x*b[j].x-b[j].y); 76 end; 77 write(ans+eps:0:3); 78 end; 79 80 begin 81 init; 82 end.