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;
    // }
    
  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/Foreign/p/15320647.html
Copyright © 2011-2022 走看看