作为今天膜你抄模拟赛上唯一切掉的题目,小w在此氵一篇题解。
链接
题目
题目描述
有一个长度为(n)的实数序列,下标从(1)开始,其中第(k)个位置的实数为(pcdot(sin(acdot k+b)+cos(ccdot +d)+2)),(sin)和(cos)采用弧度制,其中(p,a,b,c,d)均为给定的整数。
你需要从这个序列中选择两个位置(可以相同),使前边的位置上的数字减去后边的位置上的数字最大。
如果选择了两个相同的位置,那么差为(0)。
输入格式
从文件weight.in中读入数据。
一行六个整数(p,a,b,c,d,n)。
输出格式
输出到文件weight.out中。
一行一个实数表示最大的差值,保留六位小数。
样例
小w破天荒地给了样例。
样例输入
100 432 406 867 60 1000
样例输出
399.303813
数据范围与提示
对于(30\%)的数据,(1leq p,a,b,c,dleq 1000),(1leq n leq 1000);
对于(100\%)的数据,(1leq p,a,b,c,dleq 1000),(1leq n leq 10^6)。
思路
这道题居然后(sin)和(cos)!小w哭了,于是试了试cmath
发现,果然有可以!
那我们就读入,然后处理,最后sort
一遍排个序,用最大值减去最小值就好了呗~
(Code) (1)
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1000007
double qwq[MAXN] = {0.000000};
int p, a, b, c, d, n;
int main()
{
freopen("weight.in", "r", stdin);
freopen("weight.out", "w", stdout);
scanf("%d%d%d%d%d%d", &p, &a, &b, &c, &d, &n);
for (int i = 1; i <= n; i++)
{
qwq[i] = p * (sin(a * i + b) + cos(c * i + d) + 2);
}
sort(qwq + 1, qwq + 1 + n);
printf("%0.6lf", qwq[n] - qwq[1]);
fclose(stdin);
fclose(stdout);
return 0;
}
复杂度(O(nlogn))
一切看起来都是辣么完美。
但是!
但是
使前边的位置上的数字减去后边的位置上的数字最大
也就是说,顺序并不能打乱!
也就是说,不能用sort
!
那么,我们换个思路
思路 (2)
我们先考虑打暴力,直接两重循环枚举每两个数的差然后取最大值。
(Code) (2)
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1000007
double qwq[MAXN] = {0.000000};
int p, a, b, c, d, n;
int main()
{
freopen("weight.in", "r", stdin);
freopen("weight.out", "w", stdout);
scanf("%d%d%d%d%d%d", &p, &a, &b, &c, &d, &n);
for (int i = 1; i <= n; i++)
{
qwq[i] = p * (sin(a * i + b) + cos(c * i + d) + 2);
}
double maxn = -MAXN;
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= n; j++)
{
if (qwq[i] - qwq[j] > maxn)
{
maxn = qwq[i] - qwq[j];
}
}
}
printf("%0.6lf", maxn);
fclose(stdin);
fclose(stdout);
return 0;
}
这样的话……复杂度(O(n^2))
太慢了啊喂!
思路 (3)
这时,小w灵机一动!我们可以直接把处理放到预处理中!
我们在预处理的循环中,找出目前最大值的下标,然后用目前最大值减去目前的值,若比之前最大值减目前的值大,就更新,最后输出。
(Code) (3(AC))
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1000007
double qwq[MAXN] = { 0.000000 };
double maxn = -MAXN;
int p, a, b, c, d, n, awa;
int main()
{
freopen("weight.in", "r", stdin);
freopen("weight.out", "w", stdout);
scanf("%d%d%d%d%d%d", &p, &a, &b, &c, &d, &n);
for (int i = 1; i <= n; i++)
{
qwq[i] = p * (sin(a * i + b) + cos(c * i + d) + 2);
if (qwq[awa] - qwq[i] > maxn)
{
maxn = qwq[awa] - qwq[i];
}
if (qwq[i] > qwq[awa])
{
awa = i;
}
}
printf("%0.6lf", maxn);
fclose(stdin);
fclose(stdout);
return 0;
}
这样,复杂度成功降到(O(n))!
题解 · 完