2.1 题目描述
路上挂着一些灯,第 i 个灯坐标为(xi, yi) 。每个灯的照射范围为一个三角形,半张角为 zi 。
你有一架飞机,但是只能飞固定高度。由于未知原因(目测秋锅农气过重),飞机只能在光下
飞行。你的任务是找一个最大的高度来从 L 飞到R 。
如图,红线所示高度是一个合法高度,但是不是最高的。
2.2 输入格式
第一行三个数 n,L,R ,其中n 是整数,表示灯的个数。
接下来 n行,每行 3 个实数x, y, z ,描述一个灯。
2.3 输出格式
一行一个数,表示最大高度。至少保留 6 位小数。你的答案正确,当且仅当与标准输出相对误差或绝对误差不超过 10− 。
2.4 样例输入
2 3.2 7.3
3.2 4.7 28
7.3 4.2 75
2.5 样例输出
3.300759642
2.6 数据范围
对于 30%的数据:n ≤ 5, y ≤ 5
对于 60%的数据:n ≤ 30000
对于 100%的数据:n ≤ 10^5, 0 < y ≤ 10^3, 15 ≤ z ≤ 75,−10^3≤ x,L,R ≤ 10^3
好吧,大神们一眼看出的二分答案 = =。
小小地注意一下需要转弧度制。
把三角形按照x[i]从小到大离散化之后,从1一直扫到n,满足now(现在位置)>x[i]-tmp 并且now<x[i]+tmp就可以将now移到x[i]+tmp。
如果now能移到终点则是可行的。
program Neayo; const inf='light.in'; ouf='light.out'; var i,j,k,m,n:longint; exp,sr,sl,l,r:extended; x,y,tan:array[0..100001]of extended; procedure qsort(l,r:longint); var tmp,xx:extended; i,j:longint; begin i:=l;j:=r; xx:=x[l+random(r-l+1)]; repeat while x[i]<xx do inc(i); while x[j]>xx do dec(j); if i<=j then begin tmp:=x[i];x[i]:=x[j];x[j]:=tmp; tmp:=y[i];y[i]:=y[j];y[j]:=tmp; tmp:=tan[i];tan[i]:=tan[j];tan[j]:=tmp; inc(i); dec(j); end; until(i>j); if i<r then qsort(i,r); if l<j then qsort(l,j); end; procedure init; var tmp,z:extended; begin assign(input,inf);assign(output,ouf); reset(input);rewrite(output); readln(n,sl,sr); tmp:=pi/180; for i:=1 to n do begin readln(x[i],y[i],z); tan[i]:=sin(z*tmp)/cos(z*tmp); end; qsort(1,n); close(input); end; function judge(h:extended):boolean; var now,tmp:extended; begin now:=sl; for i:=1 to n do begin tmp:=(y[i]-h)*tan[i]; if now>x[i]-tmp then begin if x[i]+tmp>now then now:=tmp+x[i]; end; end; if now>sr then exit(true) else exit(false); end; procedure go; begin l:=0; r:=1000; exp:=1e-8; while r-l>exp do begin if judge((r+l)/2) then l:=(r+l)/2 else r:=(r+l)/2; end; writeln(l:0:7); end; begin init; go; close(output); end.