zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 114 (Rated for Div. 2) 题解

    旅行传送门

    A. Regular Bracket Sequences

    题意:给你一个整数 \(n\) ,构造并打印长度为 \(2n\)\(n\) 个不同的合法括号序列。

    题目分析:模拟,不妨设最初的括号序列为 \(\underbrace{(((}_{n} \cdots \underbrace{)))}_{n}\) ,每次从中取出一对合法括号放外边即可。

    AC代码

    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); i++)
    #define down(i, x, y) for (register int i = (x); i >= (y); i--)
    
    char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    void solve()
    {
        int n = read();
        down(k, n, 1)
        {
            rep(i, 1, k) printf("(");
            rep(i, 1, k) printf(")");
            rep(j, 1, n - k) printf("()");
            puts("");
        }
    }
    
    int main(int argc, char const *argv[])
    {
        int T = read();
        while (T--)
            solve();
        return 0;
    }
    

    B. Combinatorics Homework

    题意:给你四个整数值 \(a\)\(b\)\(c\)\(m\)

    判断是否存在包含以下内容的字符串:

    • \(a\) 个字母 \(A\)
    • \(b\) 个字母 \(B\)
    • \(c\) 个字母 \(C\)
    • 正好含有 \(m\) 对相邻的相等字母(即 \(s[i] = s[i+1]\) )。

    题目分析:不妨假设 \(a \leq b \leq c\) ,先考虑相邻相等字母的上下限:

    • 上限:\(\underbrace{AAA}_{a} \cdots \underbrace{BBBB}_{b} \cdots \underbrace{CCCCC}_{c}\) ,即 \((a-1)+(b-1)+(c-1)\)
    • 下限:\(\underbrace{CACA}_{a个C} \cdots \underbrace{CBCBCB}_{b个C} \cdots CCCCC\) ,即 \(c - (a+b) - 1\)

    可以证明,若 \(min \leq m \leq max\) ,则这样的序列一定存在。

    • \(min +1\)\(\underbrace{ACACA \cdots CA}_{a-1个C} \underbrace{CBCBCB}_{b个C} \cdots CCCCC+C\)
    • \(min +2\)\(\underbrace{CACA \cdots CAA}_{a-1个C} \underbrace{CBCBCB}_{b个C} \cdots CCCCC+C\)

    \(min\) 的基础上每多出一对邻相等字母,就把字符串的头字母放到该字母最后一次出现的位置之后。

    AC代码

    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); i++)
    #define down(i, x, y) for (register int i = (x); i >= (y); i--)
    
    char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    bool solve()
    {
        int a = read(), b = read(), c = read(), m = read();
        if (c < a)
            std::swap(a, c);
        if (c < b)
            std::swap(b, c);
        int mx = a + b + c - 3, mn = std::max(c - (a + b) - 1, 0);
        return (mn <= m && m <= mx) ? true : false;
    }
    
    int main(int argc, char const *argv[])
    {
        int T = read();
        while (T--)
            puts(solve() ? "YES" : "NO");
        return 0;
    }
    

    C. Slay the Dragon

    题意很久很久以前,巨龙突然出现

    你有一支含 \(n\) 位勇者的小队,现在有 \(m\) 条恶龙,第 \(i\) 条的防御为 \(x_i\) ,攻击力为 \(y_i\) 。对每条龙,你可以选出一名能力值 \(a_i \geq x_i\) 的勇者诛戮恶龙,其余勇者留下来防守,且防守的勇者们能力值总和 \(sum \geq y_i\)

    同时,你可以花费 \(1\)\(cost\) 将任意勇者的能力值提升 \(1\) 点,此操作可以进行任意次。

    问击败第 \(i\) 条龙的最小花费是多少(对战每条龙时所有勇者的能力值重置)。

    题目分析:采取贪心策略,找到序列中首次出现的 \(\geq\)\(\leq x_i\) 的值 \(a_i\) ,然后计算相应花费输出较小的即可。

    AC代码

    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); i++)
    #define down(i, x, y) for (register int i = (x); i >= (y); i--)
    using ll = long long;
    using namespace std;
    
    char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    inline ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    inline bool cmp(ll a, ll b) { return a > b; }
    
    int main(int argc, char const *argv[])
    {
        int n = read();
        ll sum = 0;
        vector<ll> a(n + 1), b(n + 1);
        rep(i, 1, n) sum += (a[i] = b[i] = read());
        sort(a.begin() + 1, a.begin() + n + 1);
        sort(b.begin() + 1, b.begin() + n + 1, cmp);
        int m = read();
        while (m--)
        {
            ll x = read(), y = read();
            int pos1 = lower_bound(a.begin() + 1, a.begin() + n + 1, x) - a.begin();
            int pos2 = lower_bound(b.begin() + 1, b.begin() + n + 1, x, greater<ll>()) - b.begin();
            if (pos1 > n)
                pos1 = n;
            if (pos2 > n)
                pos2 = n;
            ll ans1 = 0, ans2 = 0;
            if (x > a[pos1])
                ans1 += x - a[pos1];
            if (y > sum - a[pos1])
                ans1 += y - (sum - a[pos1]);
            if (x > b[pos2])
                ans2 += x - b[pos2];
            if (y > sum - b[pos2])
                ans2 += y - (sum - b[pos2]);
            printf("%lld\n", min(ans1, ans2));
        }
        return 0;
    }
    

    D. The Strongest Build

    题意:给你 \(n\) 个装备槽,每个装备槽有 \(c\) 件装备可以挑选,每件装备的属性值为 \(a_{i,j}\) ,现有 \(m\) 种不合法的方案数,求在此条件下使得属性值最大的组合方案。

    题目分析:一开始用 \(dfs\) 暴搜结果 \(MLE\) 了。这里给出一种贪心的策略,优先用更好的装备,第 \(i\) 个装备槽只考虑能使方案合法的最好的第 \(j\) 个装备,每次从优先队列中取出当前最优方案,如果这个方案已经被 \(ban\) 了,就将其分成 \(n\) 个后继方案(一个方案的后继就是对于当前组合里的某个槽,用刚好差一档的装备换上去),但分出的后继方案可能会有重复的,因此我们选择用 \(set\) 去重。由于优先队列采取的是大根堆,所以这样的做法一定能得到最优解。

    AC代码

    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i < (y); i++)
    #define down(i, x, y) for (register int i = (x); i > (y); i--)
    #define piv std::pair<int, std::vector<int>>
    
    char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    std::vector<int> v, g;
    std::map<std::vector<int>, int> mp;
    std::priority_queue<piv> q;
    std::vector<std::vector<int>> f;
    std::set<std::vector<int>> s;
    
    int main(int argc, char const *argv[])
    {
        int n = read(), sum = 0;
        rep(i, 0, n)
        {
            int c = read();
            v.push_back(c);
            g.clear();
            rep(j, 0, c)
            {
                int k = read();
                g.push_back(k);
            }
            f.push_back(g);
            sum += g[c - 1];
        }
        q.push(std::make_pair(sum, v));
        int m = read();
        rep(i, 0, m)
        {
            g.clear();
            rep(j, 0, n)
            {
                int k = read();
                g.push_back(k);
            }
            ++mp[g];
        }
        while (!q.empty())
        {
            piv ans = q.top();
            q.pop();
            sum = ans.first;
            g = ans.second;
            if (mp[g])
            {
                rep(i, 0, n)
                {
                    if (g[i] <= 1)
                        continue;
                    int cur = f[i][g[i] - 1];
                    --g[i];
                    int nxt = f[i][g[i] - 1];
                    if (!s.count(g))
                    {
                        q.push(std::make_pair(sum - cur + nxt, g));
                        s.insert(g);
                    }
                    ++g[i];
                }
                continue;
            }
            for (auto x : g)
                printf("%d ", x);
            puts("");
            break;
        }
        return 0;
    }
    
    // 关于dfs:它死了
    // #include <bits/stdc++.h>
    // #define rep(i, x, y) for (register int i = (x); i <= (y); i++)
    // #define down(i, x, y) for (register int i = (x); i >= (y); i--)
    // #define pii pair<int, int>
    // using namespace std;
    
    // char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
    // #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    // inline int read()
    // {
    //     int x = 0, f = 1;
    //     char ch = getchar();
    //     while (!isdigit(ch))
    //     {
    //         if (ch == '-')
    //             f = -1;
    //         ch = getchar();
    //     }
    //     while (isdigit(ch))
    //     {
    //         x = x * 10 + ch - '0';
    //         ch = getchar();
    //     }
    //     return x * f;
    // }
    // inline char qrc()
    // {
    //     char c;
    //     while (!isdigit(c = getchar()))
    //         ;
    //     return c;
    // }
    
    // int n, ans;
    // map<vector<int>, int> mp;
    // vector<int> output;
    // vector<pii> a[11];
    
    // void dfs(int id, vector<int> v)
    // {
    //     if (v.size() == n)
    //     {
    //         if (mp[v])
    //             return;
    //         int ans = 0;
    //         rep(i, 1, n)
    //             ans += a[i][v[i - 1] - 1].second;
    //         if (ans > ans)
    //             ans = ans, output = v;
    //         return;
    //     }
    //     for (auto x : a[id])
    //     {
    //         v.push_back(x.first);
    //         dfs(id + 1, v);
    //         v.pop_back();
    //     }
    // }
    
    // int main(int argc, char const *argv[])
    // {
    //     n = read();
    //     rep(i, 1, n)
    //     {
    //         int c = read();
    //         rep(j, 1, c)
    //         {
    //             int k = read();
    //             a[i].push_back(make_pair(j, k));
    //         }
    //     }
    //     int m = read();
    //     rep(i, 1, m)
    //     {
    //         vector<int> v;
    //         rep(j, 1, n)
    //         {
    //             int k = read();
    //             v.push_back(k);
    //         }
    //         ++mp[v];
    //     }
    //     vector<int> v;
    //     dfs(1, v);
    //     for (auto x : output)
    //         printf("%d ", x);
    //     puts("");
    //     return 0;
    // }
    
  • 相关阅读:
    Promise小结 ES6异步编程
    XLNet模型
    BERT模型
    Transformer模型
    注意力机制(Attention Mechanism)
    序列到序列模型(seq2seq)
    【Pandas-附件2】查询手册
    【Pandas-附件1】读取excle和csv具体函数
    【pandas-21】实践-同比和环比指标
    【pandas-20】实践(泰坦尼克沉船事件)-特征处理
  • 原文地址:https://www.cnblogs.com/Foreign/p/15320647.html
Copyright © 2011-2022 走看看