在幻想乡,雾雨魔理沙是住在魔法之森普通的黑魔法少女。话说最近魔理沙从香霖堂拿到了升级过后的的迷你八卦炉,她迫不及待地希望试试八卦炉的威力。在一个二维平面上有许多毛玉(一种飞行生物,可以视为点),每个毛玉具有两个属性,分值value和倍率mul。八卦炉发射出的魔法炮是一条无限长的直线形区域,可以视为两条倾斜角为α的平行线之间的区域,平行线之间的距离可以为任意值,如下图所示:
蓝色部分上下两条长边之间就是这次八卦炉的攻击范围,在蓝色范围内的毛玉(红点)属于该此被击中的毛玉,如果一个毛玉刚好在边界上也视为被击中。毛玉击中以后就会消失,每次发射八卦炉得到分值是该次击中毛玉的分值和乘上这些毛玉平均的倍率,设该次击中的毛玉集合为S,则分值计算公式为:
Score = SUM{value[i] | i 属于 S} * SUM{mul[i] | i 属于 S} / |S|
其中|S|表示S的元素个数。魔理沙将会使用若干次八卦炉,直到把所有毛玉全部击中。任意两次攻击的范围均不重叠。最后得到的分值为每次攻击分值之和。现在请你计算出能够得到的最大分值。
Input
第1行:1个整数N,表示毛玉个数
第2..N+1行:每行四个整数x, y, value, mul,表示星星的坐标(x,y),以及value和mul
第N+2行:1个整数α,表示倾斜角角度,0°到180°
Output
第1行:1个实数,表示最大分值,保留三位小数
Sample Input
3
1 3 3 1
2 1 2 2
3 4 2 1
45
Sample Output
9.333
Data Constraint
Hint
【数据范围】
对于60%的数据:1 <= N <= 500
对于100%的数据:1 <= N <= 2,000
-10,000 <= x,y <= 10,000
1 <= value,mul <= 100
【注意】
π = 3.1415926
分析:我们知道当一个角的度数已知时,它对边与临边的比为L=tanh(度数)。
例如:tanh(45)=1。
然后我们知道斜边一次函数解析式为y=Lx+b。把每个点的横纵坐标代入得出b。并将这些点平移到y轴上。
如图,A移动到A’,B移动到B’,C移动到A’点。
然后把在同一点上的全部点缩为一个(一定同一次轰掉)。然后dp一下,就AC了。可以用Pascal的math库中有ton。tanh(45)=tan(45*π/180)。
代码:
const
hehe:array [1..89] of real=(0.017455065,0.034920769,0.052407779,0.069926812,0.087488664,0.105104235,0.122784561,0.140540835,0.15838444,0.176326981,
0.194380309,0.212556562,0.230868191,0.249328003,0.267949192,0.286745386,0.305730681,0.324919696,0.344327613,0.363970234,0.383864035,0.404026226,0.424474816,
0.445228685,0.466307658,0.487732589,0.509525449,0.531709432,0.554309051,0.577350269,0.600860619,0.624869352,0.649407593,0.674508517,0.700207538,
0.726542528,0.75355405,0.781285627,0.809784033,0.839099631,0.869286738,0.900404044,0.932515086,0.965688775,1,
1.035530314,1.07236871,1.110612515,1.150368407,1.191753593,1.234897157,1.279941632,1.327044822,1.37638192,1.428148007,
1.482560969,1.539864964,1.600334529,1.664279482,1.732050808,1.804047755,1.880726465,
1.962610506,2.050303842,2.144506921,2.246036774,2.355852366,2.475086853,2.605089065,2.747477419,2.904210878,3.077683537,3.270852618,
3.487414444,3.732050808,4.010780934,4.331475874,4.704630109,
5.144554016,5.67128182,6.313751515,7.115369722,8.144346428,9.514364454,11.4300523,14.30066626,19.08113669,28.63625328,57.2899616308);
const
minn=0.00000001;
var
v,m,x,y,sumv,summ:array [0..2000] of longint;
p:array [0..2000] of real;
f:array [0..2000] of real;
n,i,j,pig:longint;
t:real;
procedure qsort(l,r:longint);
var
i,j,temp:longint;
key:real;
temp1:real;
begin
if l>=r then exit;
i:=l;j:=r;
key:=p[l+random(r-l+1)];
repeat
while (p[i]<key) do inc(i);
while (p[j]>key) do dec(j);
if i<=j then
begin
temp1:=p[i];p[i]:=p[j];p[j]:=temp1;
temp:=x[i];x[i]:=x[j];x[j]:=temp;
temp:=y[i];y[i]:=y[j];y[j]:=temp;
temp:=v[i];v[i]:=v[j];v[j]:=temp;
temp:=m[i];m[i]:=m[j];m[j]:=temp;
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
function max(x,y:real):real;
begin
if x>y then exit(x)
else exit(y);
end;
begin
readln(n);
for i:=1 to n do
readln(x[i],y[i],v[i],m[i]);
readln(pig);
for i:=1 to n do
begin
if (pig=180) or (pig=0) then p[i]:=y[i]
else if pig=90 then p[i]:=x[i]
else
begin
if pig>90 then t:=-hehe[180-pig]
else t:=hehe[pig];
p[i]:=y[i]-t*x[i];
end;
end;
qsort(1,n);
p[0]:=-165498189165155478;
for i:=1 to n do
begin
sumv[i]:=sumv[i-1]+v[i];
summ[i]:=summ[i-1]+m[i];
end;
f[1]:=v[1]*m[1];
for i:=2 to n do
for j:=0 to i-1 do
begin
if abs(p[i]-p[j])<minn then continue;
f[i]:=max(f[i],f[j]+(sumv[i]-sumv[j])*((summ[i]-summ[j])/(i-j)));
end;
writeln(f[i]:0:3);
end.