zoukankan      html  css  js  c++  java
  • YbtOJ20029 最大权值

    作为今天膜你抄模拟赛上唯一切掉的题目,小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))

    题解 · 完

  • 相关阅读:
    java 8 lambda函数
    java nio和io
    jetty xml解析
    使用spring框架时,使用xml还是注解
    tcp/ip基础知识
    http的session和cookie
    html相关
    form之action的绝对路径与相对路径(转载)
    MariaDB 10 (MySQL DB) 多主复制并实现读写分离
    牛刀小试MySQL学习—MySQL 双主
  • 原文地址:https://www.cnblogs.com/w-rb/p/13974498.html
Copyright © 2011-2022 走看看