zoukankan      html  css  js  c++  java
  • Codeforces Round #674 (Div. 3)

    比赛链接:https://codeforces.com/contest/1426

    A. Floor Number

    题意

    一所房子除第一层有 $2$ 个房间外其余层有 $x$ 个房间,给出房间号 $n$,问该房间在第几层。

    题解

    既然除了第一层外每层房间数都相等,那么只需计算在第一层的基础上还需加上几层即可,即 $1 + lceil frac{n-2}{x} ceil$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, x;
            cin >> n >> x;
            cout << 1 + (max(0, n - 2) + x - 1) / x << "
    ";
        }
        return 0;
    }

    B. Symmetric Matrix

    题意

    给出 $n$ 个 $2 imes 2$ 的小正方矩阵和大正方矩阵的边长 $m$,小矩阵每个位置有一个数,每个小矩阵使用次数不限,问能否用小矩阵完全填补大矩阵且大矩阵关于主对角线对称。

    题解

    只要至少有一个小矩阵关于主对角线对称即可,其次为了完全填补,大矩阵的边长需要为 $2$ 的倍数。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, m;
            cin >> n >> m;
            bool ok = false;
            for (int i = 0; i < n; i++) {
                int a, b, c, d;
                cin >> a >> b >> c >> d;
                if (b == c) ok = true;
            }
            cout << (ok and m % 2 == 0 ? "YES" : "NO") << "
    ";
        }
        return 0;
    }

    C. Increase and Copy

    题意

    一开始数组中只有一个值为 $1$ 的数,每次操作可以选择:

    • 给一个数加一
    • 在末尾添加一个已有的数

    问使得所有数之和为 $n$ 的最少操作次数。

    题解

    $n = a imes b + c$,枚举 $a$ 即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            int ans = INT_MAX;
            for (int i = 1; i * i <= n; i++) {
                ans = min(ans, (i - 1) + (n / i - 1) + (n % i != 0));
            }
            cout << ans << "
    ";
        }
        return 0;
    }

    D. Non-zero Segments

    题意

    计算使一个数组没有和为 $0$ 的连续区间至少要插入多少个数。

    题解

    计算前缀和,如果当前和在之前出现过,那么说明之前有一段和为 $0$ 的区间,插入一个数后清空之前的记录从当前数重新计算即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        int ans = 0;
        set<long long> st;
        st.insert(0);
        long long sum = 0;
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            sum += x;
            if (st.count(sum)) {
                ++ans;
                st.clear();
                st.insert(0);
                st.insert(sum = x);
            } else {
                st.insert(sum);
            }
        }
        cout << ans << "
    ";
        return 0;
    }

    E. Rock, Paper, Scissors

    题意

    给出 $Alice$ 和 $Bob$ 各会出石头剪刀布的次数,问 $Alice$ 至少和至多会赢多少次。

    题解

    最多赢多少次比较好想,即 $min(a_1,b_2) + min(a_2,b_3) + min(a_3,b_1) $ 。

    最少赢多少次应考虑那些不得不赢的情况,即减去输掉和平局的所有局数后还有余的次数,可以证明这种情况最多只有一种。

    证明

    如果存在两个 $a_i - b_i - b_{i+2} > 0$,比如 $a_1 > b_1 + b_3$,$a_2 > b_2 + b_1$,那么 $a_1 + a_2 > b_1 + b_2 + b_3 + b_1 = n + b_1$,即 $a_1 + a_2 > n$,与 $a_1 + a_2 + a_3 = n$ 矛盾,所以不得不赢的情况至多只存在一种。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        vector<int> a(3), b(3);
        for (auto &x : a) cin >> x;
        for (auto &x : b) cin >> x;
        int ans1 = 0, ans2 = 0;
        for (int i = 0; i < 3; i++) {
            ans1 = max(ans1, a[i] - b[(i + 2) % 3] - b[i]);
        }
        for (int i = 0; i < 3; i++) {
            ans2 += min(a[i], b[(i + 1) % 3]);
        }
        cout << ans1 << ' ' << ans2 << "
    ";
        return 0;
    }

    F. Number of Subsequences

    题意

    一个字符串由 $a,b,c$ 和 $k$ 个 $?$ 组成,$?$ 可以被替换为 $a,b,c$,问在 $3^k$ 个可能的字符串中共有多少个 $abc$ 序列。

    题解

    $dp_0$——字符串的个数

    $dp_1$——$a$序列的个数

    $dp_2$——$ab$序列的个数

    $dp_3$——$abc$序列的个数

    代码

    #include <bits/stdc++.h>
    using namespace std;
    constexpr int MOD = 1e9 + 7;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        string s;
        cin >> s;
        vector<long long> dp(4);
        dp[0] = 1;
        for (char c : s) {
            if (c == '?') {
                for (int i = 3; i > 0; i--) dp[i] = (dp[i] * 3 + dp[i - 1]) % MOD;
                dp[0] = dp[0] * 3 % MOD;            
            } else {
                int i = c - 'a' + 1;
                (dp[i] += dp[i - 1]) %= MOD;
            }
        }
        cout << dp[3] << "
    ";
        return 0;
    }

    参考博客

    https://blog.csdn.net/tomjobs/article/details/108858505

  • 相关阅读:
    微信小程序开发(十一)获取手机的完整详细信息
    24小时学通Linux内核总结篇(kconfig和Makefile & 讲不出再见)
    24小时学通Linux内核之向内核添加代码
    24小时学通Linux内核之构建Linux内核
    24小时学通Linux内核之电源开和关时都发生了什么
    24小时学通Linux内核之调度和内核同步
    24小时学通Linux内核之有关Linux文件系统实现的问题
    24小时学通Linux内核之如何处理输入输出操作
    24小时学通Linux内核之内存管理方式
    24小时学通Linux内核之进程
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13765639.html
Copyright © 2011-2022 走看看