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

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

    A. Stone Game

    题解

    从一侧取:两种情况

    从两侧取:一种情况

    取三种情况的最小值。

    代码

    #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;
            vector<int> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            int p1 = min_element(a.begin(), a.end()) - a.begin();
            int p2 = max_element(a.begin(), a.end()) - a.begin();
            cout << min({max(p1, p2) + 1,  n - min(p1, p2), (min(p1, p2) + 1) + (n - max(p1, p2))}) << "
    ";
        }
        return 0;
    }
    

    B. Friends and Candies

    题解

    如果总和不能平分则无解,否则将多于平均的数重新分配。

    代码

    #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;
            vector<int> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            sort(a.begin(), a.end());
            int sum = accumulate(a.begin(), a.end(), 0);
            if (sum % n != 0) {
                cout << -1 << "
    ";
            } else {
                cout << n - (upper_bound(a.begin(), a.end(), sum / n) - a.begin()) << "
    ";
            }
        }
        return 0;
    }
    

    C. Number of Pairs

    题解

    二分所能加的数的左右边界。

    代码

    #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, l, r;
            cin >> n >> l >> r;
            vector<int> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            sort(a.begin(), a.end());
            long long ans = 0;
            for (int i = 0; i < n; i++) {
                auto it1 = lower_bound(a.begin() + i + 1, a.end(), l - a[i]);
                auto it2 = upper_bound(a.begin() + i + 1, a.end(), r - a[i]);
                ans += it2 - it1;           
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    

    D. Another Problem About Dividing Numbers

    题解

    最少操作次数:将 (a,b)(gcd(a, b)) 转化,

    • (gcd(a, b) = a)(gcd(a, b) = b) 时,最少操作 (0)
    • (gcd(a, b) = a)(gcd(a, b) = b) 时,最少操作 (1)
    • (gcd(a, b) e a)(gcd(a, b) e b) 时,最少操作 (2)

    最多操作次数:将 (a, b)(1) 转化,为两者所有质因子的幂次之和。

    如果 (k) 位于两者之间则有解。

    因为最少操作次数为 (2) 次,所以特判 (k = 1) 的情况,然后判断 (k) 是否小于最多操作次数即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        constexpr int N = 1e5;
        vector<int> isPrime(N, true);
        for (int i = 2; i < N; i++) {
            for (int j = i + i; j < N; j += i) {
                isPrime[j] = false;
            }
        }
        vector<int> Primes;
        for (int i = 2; i < N; i++) {
            if (isPrime[i]) {
                Primes.push_back(i);
            }
        }
        int t;
        cin >> t;
        while (t--) {
            int a, b, k;
            cin >> a >> b >> k;
            if (k == 1) {
                if (a == b) {
                    cout << "NO" << "
    ";
                } else if (a % b == 0 or b % a == 0) {
                    cout << "YES" << "
    ";
                } else {
                    cout << "NO" << "
    ";
                }
                continue;
            }
            auto Count_Expo = [&](int n) {
                int res = 0;
                for (auto i : Primes) {
                    while (n % i == 0) {
                        ++res;
                        n /= i;
                    }
                }
                if (n != 1) {
                    ++res;
                }
                return res;
            };
            cout << (k <= Count_Expo(a) + Count_Expo(b) ? "YES" : "NO") << "
    ";
        }
        return 0;
    }
    

    E. Funny Substrings

    题解

    因为 (haha) 长为 (4) ,所以保存一个字符串首尾的 (3) 个字符及 (haha) 的个数。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct P{
        string front;
        string back;
        long long cnt_haha = 0;
    };
    P cal(const string& s) {
        P res;
        res.front = s.substr(0, 3);
        res.back = s.substr(max(0, (int)s.size() - 3));
        for (int i = 0; i < (int)s.size(); i++) {
            if (s.substr(i, 4) == "haha") {
                ++res.cnt_haha;
            }
        }
        return res;
    }
    P merge(const P& a, const P& b) {
        P res;
        res.front = (a.front + b.front).substr(0, 3);
        res.back = (a.back + b.back).substr(max(0, (int)a.back.size() + (int)b.back.size() - 3));
        res.cnt_haha = a.cnt_haha + b.cnt_haha + cal(a.back + b.front).cnt_haha;
        return res;
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            map<string, P> mp;
            for (int i = 0; i < n; i++) {
                string name, op;
                cin >> name >> op;
                if (op == ":=") {
                    string str;
                    cin >> str;
                    mp[name] = cal(str);
                } else if (op == "=") {
                    string a, b;
                    char ch;
                    cin >> a >> ch >> b;
                    mp[name] = merge(mp[a], mp[b]); 
                }
                if (i == n - 1) {
                    cout << mp[name].cnt_haha << "
    ";
                }
            }
        }
        return 0;
    }
    

    F. Interesting Function

    题解

    依次计算每一位对前一位产生了多少进位。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int l, r;
            cin >> l >> r;
            string s1 = to_string(l), s2 = to_string(r);
            s1 = string(s2.size() - s1.size(), '0') + s1;
            int ans = 0, carry = r - l;
            for (int i = s1.size() - 1; i >= 0; i--) {
                ans += carry;
                carry = (carry + s1[i] - '0') / 10;
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    

    G. Gift Set

    题解

    因为总次数具有单调性,所以考虑对其二分。

    若某次所二分的总次数值为 (n) ,假设进行了操作一 (k) 次,那么有:

    • (a imes k + b imes (n - k) le x)
    • (b imes k + a imes (n - k) le y)

    不妨令 (a gt b) , 化简得:

    • (k le frac{x - b imes n}{a - b})
    • (k ge frac{y - a imes n}{b - a} = frac{a imes n - y}{a - b})

    同时,有:

    • (k ge 0)
    • (k le n)

    若上述四个不等式在数轴上有交集,则 (k) 存在,表示当前二分值 (n) 可行。

    Tips

    若分子 (a) 可能为正负整数,分母 (b) 为正整数,则有:

    • 取上整: (lfloor frac{a + b - 1}{b} floor)
    • 取下整: (lfloor frac{a + b}{b} floor - 1)

    代码

    #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, a, b;
            cin >> x >> y >> a >> b;
            if (a == b) {
                cout << min(x, y) / a << "
    ";
                continue;
            }
            if (a < b) {
                swap(a, b);
            }
            int l = 0, r = (x + y) / (a + b);
            while (l < r) {
                int n = (l + r + 1) / 2;
                int L = max(0, (a * n - y + a - b - 1) / (a - b));
                int R = min(n, (x - b * n + a - b) / (a - b) - 1);
                if (L <= R) {
                    l = n;
                } else {
                    r = n - 1;
                }
            }
            cout << l << "
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    C++ 引用的作用和用法
    const和指针
    sizeof的用法
    C++数组初始化的问题
    C++变量的存储类别(动态存储、静态存储、自动变量、寄存器变量、
    c++变量在内存中的存储区域(转)
    C语言的 &数组名 和 数组名的区别
    C语言运算中的数据类型自动转换原则
    链表反转
    常见的排序方法
  • 原文地址:https://www.cnblogs.com/Kanoon/p/14879102.html
Copyright © 2011-2022 走看看