• 2019中国大学生程序设计竞赛-女生专场(重现赛)部分题解C-Function(贪心+优先队列) H-clock(模拟)


    Function

    题目链接

    Problem Description

    wls 有 n 个二次函数 Fi(x) = aix2 + bix + ci (1 ≤ i ≤ n).
    现在他想在∑ni=1xi = m 且 x 为正整数的条件下求∑ni=1Fi(xi)的最小值。
    请求出这个最小值。

    Input

    第一行两个正整数 n, m。
    下面 n 行,每行三个整数 a, b, c 分别代表二次函数的二次项, 一次项,常数项系数。
    1 ≤ n ≤ m ≤ 100, 000
    1 ≤ a ≤ 1, 000
    −1, 000 ≤ b, c ≤ 1, 000

    Output

    一行一个整数表示答案。

    Sample Input

    2 3
    1 1 1
    2 2 2

    Sample Output

    13

    解题思路:

    利用结构体维护每个函数f(x+1)-f(x)的差值,一开始将所有函数x置为1,贪心,优先取差值小的函数,x+1并更新差值重新放入优先队列中直至用完m-n个数为止

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    #define inf 0x3f3f3f3f
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MAXN = 1e6 + 7;
    const ll MAXM = 1e3 + 7;
    const ll MOD = 1e9 + 7;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    struct node
    {
        ll a, b, c;
        ll mark;
        ll x;
        bool operator<(const node &t) const
        {
            return mark > t.mark;
        }
    };
    int main()
    {
        ll n, m;
        while (~scanf("%lld%lld", &n, &m))
        {
            priority_queue<node> pq;
            ll ans = 0;
            for (int i = 0; i < n; i++)
            {
                node t;
                scanf("%lld%lld%lld", &t.a, &t.b, &t.c);
                ans += t.a + t.b + t.c;
                t.x = 1;
                t.mark = t.a * (2 * t.x + 1) + t.b;
                pq.push(t);
            }
            for (int i = 0; i < m - n; i++)
            {
                node temp = pq.top();
                pq.pop();
                temp.x++;
                temp.mark = temp.a * (2 * temp.x + 1) + temp.b;
                pq.push(temp);
                ans += temp.a * (2 * temp.x - 1) + temp.b;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    Clock

    题目链接

    Problem Description

    wls 有一个钟表,当前钟表指向了某一个时间。
    又有一些很重要的时刻,wls 想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,wls 想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
    注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。

    Input

    第一行一个整数 n 代表有多少个时刻要访问。
    第二行三个整数 h,m,s 分别代表当前时刻的时分秒。
    最后n行每一行三个整数 hi,mi,si 代表每个要访问的时刻的时分秒。
    1 ≤ n ≤ 86, 400
    0 ≤ h, hi < 24
    0 ≤ m, mi, s, si < 60

    Output

    输出一行一个数代表秒钟转的角度,答案保留两位小数。

    Sample Input

    1
    0 1 0
    0 1 1

    Sample Output

    6.00

    解题思路:

    总共有一直顺时针转,一直逆时针转,先逆时针后顺时针,先顺时针后逆时针转四种情况,直接模拟

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    #define inf 0x3f3f3f3f
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MAXN = 1e6 + 7;
    const ll MAXM = 1e3 + 7;
    const ll MOD = 1e9 + 7;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    int main()
    {
        int n, h, m, s;
        int h1, m1, s1;
        int ans = 0;
        int suma = 12 * 3600;
        while (~scanf("%d", &n))
        {
            scanf("%d%d%d", &h, &m, &s);
            h %= 12;
            int start = h * 3600 + m * 60 + s;
            ans = 0;
            int ed1 = start, ed2 = start; //倒回去最接近0,顺下去最接近12
            int st1 = 0, st2 = suma;      //倒回去最接近起点,顺下去最接近起点
            for (int i = 0; i < n; i++)
            {
                scanf("%d%d%d", &h1, &m1, &s1);
                h1 %= 12;
                int sum = h1 * 3600 + 60 * m1 + s1;
                ed2 = max(ed2, sum);
                ed1 = min(ed1, sum);
                if (sum < start)
                    st1 = max(st1, sum);
                else if (sum > start)
                    st2 = min(sum, st2);
            }
            ans = min(min(suma - (start - st1), suma - (st2 - start)), min(start - ed1 + ed2 - ed1, ed2 - start + ed2 - ed1));
            ans *= 6;
            printf("%d.00
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    ODBC接口规范
    JDBC与ODBC
    java中newInstance()和new()
    JDBC详解
    用JDBC连接 数据库 进行简单的增删改查
    JDBC接口规范
    JDBC中常用的接口
    java中的getStackTrace和printStackTrace的区别
    linux中的strings命令
    JAVA的容器---List,Map,Set (转)
  • 原文地址:https://www.cnblogs.com/graytido/p/11185452.html
Copyright © 2020-2023  润新知