雾雨魔理沙

 在幻想乡,雾雨魔理沙是住在魔法之森普通的黑魔法少女。话说最近魔理沙从香霖堂拿到了升级过后的的迷你八卦炉,她迫不及待地希望试试八卦炉的威力。在一个二维平面上有许多毛玉(一种飞行生物,可以视为点),每个毛玉具有两个属性,分值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.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值