zoukankan      html  css  js  c++  java
  • 牛客小白月赛28

    比赛链接:https://ac.nowcoder.com/acm/contest/7412

    A - 牛牛和牛可乐的赌约

    题解

    计算模意义下的 $1 - frac{1}{n^m}$ 即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e9 + 7;
    
    int binpow(int a, int b) {
        int res = 1;
        while (b > 0) {
            if (b & 1) res = 1LL * res * a % MOD;
            a = 1LL * a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    
    int inv(int n) {
        return binpow(n, MOD - 2);
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, m;
            cin >> n >> m;
            cout << (1 - inv(binpow(n, m)) + MOD) % MOD << "
    ";
        }
        return 0;
    }

    B - 牛牛和牛可乐的赌约2

    题解

    • $(0,0)$ 为必败态
    • 可以移动到 $(0,0)$ 的 $(0,1),(0,2),(1,0),(2,0)$ 为必胜态
    • 不得不移动到 $(0,1),(0,2),(1,0),(2,0)$ 的 $(3,0),(1,1),(0,3)$ 为必败态
    • …………

    以此类推,最终推得规律为 $x \% 3 = y \% 3$ 必败。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int x, y;
            cin >> x >> y;
            cout << ((x - y) % 3 == 0 ? "awsl" : "yyds") << "
    ";
        }
        return 0;
    }

    C - 单词记忆方法

    题解

    递归求解每个配对括号内的和,再乘以括号外的倍数即可。

    Tips

    有可能括号外没有数字,所以 $dfs$ 中的 $mul$ 的初值根据判断条件有两种形式。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    constexpr int N = 1e5 + 100;
    
    string s;
    int match[N];
    
    void Match() {
        stack<int> stk;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '(') {
                stk.push(i);
            } else if (s[i] == ')') {
                int last = stk.top();
                stk.pop();
                match[i] = last;
                match[last] = i;
            }
        }
    }
    
    long long dfs(int l, int r) {
        if (l > r) return 0;
        long long res = 0;
        while (l <= r) {
            long long val = 0;
            while (l <= r and isupper(s[l])) {
                val += s[l] - 'A' + 1;
                ++l;
            }
            if (s[l] == '(') {
                val = dfs(l + 1, match[l] - 1);
                l = match[l] + 1;
            }
            long long mul = 1;
            if (l <= r and isdigit(s[l])) {
                mul = 0;
                while (l <= r and isdigit(s[l])) {
                    mul = mul * 10 + s[l] - '0';
                    ++l;
                }
            }
            res += val * mul;
        }
        return res;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cin >> s;
        Match();
        cout << dfs(0, s.size() - 1) << "
    ";
        return 0;
    }

    D - 位运算之谜

    题解

    egin{equation} a + b = x end{equation}

    egin{equation} a & b = y end{equation}

    egin{equation} a + b = a oplus b + ((a & b) << 1) end{equation}

    将 (1)(2) 代入 (3) 得:

    egin{equation} x = a oplus b + (y << 1) onumber end{equation}

    移项得:

    egin{equation} a oplus b = x - (y << 1) onumber end{equation}

    如果存在整数 $a,b$ 满足条件,那么得到的 $a oplus b$ 一定满足:

    egin{equation} a oplus b ge 0  onumber end{equation}

    egin{equation} (a oplus b) & (a & b) = 0  onumber end{equation}

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            long long x, y;
            cin >> x >> y;
            long long c = x - (y << 1);
            cout << (c >= 0 and ((c & y) == 0) ? c : -1) << "
    ";
        }
        return 0;
    }

    G - 牛牛和字符串的日常

    题解

    KMP模板题,稍微改一下求最长前缀即可。(感觉以前哪场比赛好像考过这个)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 100;
    
    int Next[N];
    string s, p;
    
    void init_Next() {
        Next[0] =Next[1] = 0;
        for (int i = 1; i < p.size(); i++) {
            int j = Next[i];
            while (j and p[i] != p[j]) j = Next[j];
            Next[i + 1] = (p[i] == p[j] ? j + 1 : 0);
        }
    }
    
    int KMP() {
        int mx = 0;
        int j = 0;
        for (int i = 0; i < s.size(); i++) {
            while (j and s[i] != p[j]) j = Next[j];
            if (s[i] == p[j]) j++;
            mx = max(mx, j);
        }
        return mx;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        long long ans = 0;
        cin >> p;
        init_Next();
        int t; 
        cin >> t;
        while (t--) {
            cin >> s;
            ans += KMP();
        }
        cout << ans << "
    ";
        return 0;
    }

    H - 上学要迟到了

    题解

    单源最短路模板题。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, m, s, t, T;
        cin >> n >> m >> s >> t >> T;
        vector<int> tim(m + 1), a(n + 1);
        for (int i = 1; i <= m; i++)
            cin >> tim[i];
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        vector<vector<pair<int, int>>> G(n + 1);
        for (int u = 1; u + 1 <= n; u++) {
            int v = u + 1;
            G[u].emplace_back(v, T);
            G[v].emplace_back(u, T);
        }
        vector<int> last(m + 1);
        for (int i = 1; i <= n; i++) {
            if (last[a[i]]) {
                int u = last[a[i]];
                int v = i;
                G[u].emplace_back(v, tim[a[i]]);
            }
            last[a[i]] = i;
        }
        function<int(int, int)> Get_distance = [&](int s, int t) {
            vector<int> dis(n + 1, 1e9);
            vector<bool> vis(n + 1);
            priority_queue<pair<int, int>> pque;
            dis[s] = 0;
            pque.emplace(0, s);
            while (!pque.empty()) {
                int u = pque.top().second;
                pque.pop();
                if (vis[u]) continue;
                vis[u] = true;
                for (auto i : G[u]) {
                    int v = i.first, w = i.second;
                    if (!vis[v] and dis[v] > dis[u] + w) {
                        dis[v] = dis[u] + w;
                        pque.emplace(-dis[v], i.first);
                    }
                }
            }
            return dis[t];
        };
        cout << Get_distance(s, t) << "
    ";
        return 0;
    }

    I - 迷宫

    题解

    计算从 $(1,1)$ 到 $(n,m)$ 的路径数目的状态转移方程为:

    egin{equation} dp_{ij} = dp_{(i-1)j} + dp_{i(j-1)} onumber end{equation}

    那么计算模数再加一维状压dp即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    constexpr int MOD = 1e4 + 7;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, m;
        cin >> n >> m;
        vector<vector<int>> a(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) {
                cin >> a[i][j];
                a[i][j] %= MOD;
            }
        vector<vector<bitset<MOD>>> dp(n + 1, vector<bitset<MOD>>(m + 1));
        dp[1][1].set(a[1][1]);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (i == 1 and j == 1) continue;
                dp[i][j] |= (dp[i - 1][j] << a[i][j]) | (dp[i - 1][j] >> (MOD - a[i][j]));
                dp[i][j] |= (dp[i][j - 1] << a[i][j]) | (dp[i][j - 1] >> (MOD - a[i][j]));
            }
        }
        cout << dp[n][m].count() << "
    ";
        return 0;
    }

    J - 树上行走

    题解

    并查集模板题

    Tips

    一个结点的父亲不一定是 $fa[i]$,应该用 $Find(i)$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    constexpr int N = 2e5 + 100;
    
    int fa[N], son_num[N];
    
    int Find(int x) {
        return fa[x] == x ? fa[x] : fa[x] = Find(fa[x]);
    }
    
    void Union(int x, int y) {
        x = Find(x);
        y = Find(y);
        if (x != y) {
            fa[y] = x;
            son_num[x] += son_num[y];
        }
    }
    
    void Init() {
        for (int i = 0; i < N; i++) {
            fa[i] = i;
            son_num[i] = 1;
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        Init();
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++)
            cin >> a[i];
        for (int i = 0; i < n - 1; i++) {
            int x, y;
            cin >> x >> y;
            --x, --y;
            if (a[x] == a[y])
                Union(x, y);
        }
        int mx = *max_element(son_num, son_num + n);
        cout << count(son_num, son_num + n, mx) * mx << "
    ";
        for (int i = 0; i < n; i++) {
            if (son_num[Find(i)] == mx) {
                cout << i + 1 << ' ';
            }
        }
        return 0;
    }
  • 相关阅读:
    JS中原型链的理解
    CSS3的笔记总结
    那些牛掰的 HTML5的API(二)
    初识 HTML5(一)
    jQuery基础知识点(下)
    jQuery基础知识点(DOM操作)
    jQuery基础知识点(上)
    [译]GC专家系列2:Java 垃圾回收的监控
    [译]GC专家系列1: 理解Java垃圾回收
    [译]深入理解JVM
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13702977.html
Copyright © 2011-2022 走看看