[SDOI2015]权值

时间:2022-12-23 04:58:10

问题描述:

有一个长度为n的实数序列,,下标从1开始,其中第k个位置的实数为p · (sin(a · k + b) + cos(c · k + d) + 2),sin和cos采用弧度制,其中p,a,b,c,d均为给定的整数。你需要从这个序列中选择两个位置(可以相同),使前边的位置上的数字减去后边的位置上的数字最大。如果选择了两个相同的位置,那么差为0.

输入:

一行六个整数p,a,b,c,d,n。

输出:

一行一个实数表示最大的差值,保留六位小数。

输入输出样例:

weight.in

weight.out

100 432 406 867 60 1000

399.303813

数据范围:

对于30%的数据,1<=p,a,b,c,d<=1000,1<=n<=1000;

对于全部的数据,1<=p,a,b,c,d<=1000,1<=n<=10^6。

思路:

  可以在线处理,一边计算,一边计算次数与前面最小数的差值,时间复杂度O(N)。

var p,a,b,c,d,n,maxx,i:longint;
ans,max:real;
f,e:array[..] of real;
begin
assign(input,'weight.in');
assign(output,'weight.out');
reset(input);
rewrite(output);
read(p,a,b,c,d,n);
for i:= to n do
begin
f[i]:=sin(a*i + b) + cos(c * i + d);
if f[i]>max then
begin
max:=f[i];
maxx:=i;
end;
e[i]:=f[maxx]-f[i];
if e[i]>ans then ans:=e[i];
end;
writeln(ans*p::);
close(input);
close(output);
end.