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

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

    A - Two Rival Students

    题意

    有 $n$ 个学生站成一排,最多使相邻两个学生交换位置 $k$ 次,给出两个学生的位置,计算这两个学生能相距的最远距离。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n, x, a, b; cin >> n >> x >> a >> b;
        cout << min(n - 1, abs(b - a) + x) << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    B - Magic Stick

    题意

    给出正整数 $x,y$,对 $x$ 可以选择执行两种操作:

    • 如果 $x$ 为偶数,将 $x$ 变为 $frac{3x}{2}$
    • 如果 $x>1$,将 $x$ 变为 $x - 1$

    判断 $x$ 能否变为 $y$ 。 

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int x, y; cin >> x >> y;
        if (x >= y or (x == 2 and y == 3)) cout << "YES" << "
    ";
        else cout << (x <= 3 ? "NO" : "YES") << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    C - Dominated Subarray

    题意

    找出一个数组大小至少为 $2$ 的最小连续子数组,要求该子数组中出现次数最多的值只有一个。

    题解

    依次计算每个值相邻两个元素的最短距离即可。

    证明

    如果一个值的相邻两个元素之间有出现两次的其他值,说明其他值相邻两个元素的距离更短,最终也一定会被取到。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n; cin >> n;
        vector<int> pos[n + 1];
        for (int i = 0; i < n; i++) {
            int x; cin >> x;
            pos[x].push_back(i);
        }
        int ans = INT_MAX;
        for (auto v : pos) {
            for (int i = 1; i < v.size(); i++) {
                ans = min(ans, v[i] - v[i - 1] + 1);
            }
        }
        cout << (ans == INT_MAX ? -1 : ans) << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    D - Yet Another Monster Killing Problem

    题意

    有 $n$ 个怪物在山洞中排成一排,每个怪物的力量为 $a_i$,你有 $m$ 个战士,每个战士的力量为 $p_i$,只有当战士的力量不低于怪物时才可以击败怪物,每个战士一天最多击败 $s_i$ 只怪物。一天只能选派一个战士,计算击败全部怪物所需的最少天数。(怪物被击败后不会复活)

    题解

    预处理一遍得到耐久度至少为 $i$ 的战士的最大力量 $mx_i$,之后利用双指针模拟,每天尽可能多地击败怪物即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n; cin >> n;
        int a[n] = {};
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        int m; cin >> m;
        int mx[n + 1] = {};
        for (int i = 0; i < m; i++) {
            int p, m; cin >> p >> m;
            mx[m] = max(mx[m], p);
        }
        for (int i = n - 1; i >= 0; i--) {
            mx[i] = max(mx[i], mx[i + 1]);
        }
        int ans = 0;
        for (int i = 0; i < n; ) {
            int j = i, maxn = a[i];
            while (j < n and mx[j - i + 1] >= maxn) {
                ++j;
                maxn = max(maxn, a[j]);
            }
            if (j == i) {
                ans = -1;
                break;
            } else {
                ++ans;
                i = j;
            }
        }
        cout << ans << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    E - The Contest

    题意

    三个人各持有一个排列的子序列,要求使第一个人持有排列的前一部分,第二个人持有排列的中间一部分,第三个人持有排列的后一部分,三人间至少要移动多少个元素。(可以移动一个人的全部元素)

    题解

    参考自:qscqesze

    逆向考虑,将每个人持有的元素排序后合并为一个序列,最多不需移动的元素个数即为该序列的最长上升子序列。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 100;
    int k1, k2, k3, n;
    int a[N], b[N], dp[N];
    
    int lis() {
        int len = 1;
        b[1] = a[0];
        for (int i = 1; i < n; i++) {
            b[len + 1] = n + 1;
            int l = 0, r = len + 1, ans = 0;
            while (l <= r) {
                int mid = (l + r) / 2;
                if (a[i] < b[mid]) {
                    ans = mid;
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            b[ans] = a[i];
            if (ans > len) ++len;
        }
        return n - len;
    }
    
    int main() {
        cin >> k1 >> k2 >> k3;
        n = k1 + k2 + k3;
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        sort(a, a + k1);
        sort(a + k1, a + k1 + k2);
        sort(a + k1 + k2, a + k1 + k2 + k3);
        cout << lis() << "
    ";    
    }
  • 相关阅读:
    你为什么老是找不到满意的工作? 多思考自己的原因 !
    微信企业号开发之-如何获取secret 序列号
    可以免费自学编程的12个网站
    软件职业:聊聊学习这件事!
    致行业初学者:关于某些培训机构,老徐聊几句,也许对你们有用
    查看centos版本号
    配置mysql远程访问权限,大家可能掉过的那些坑~
    测试必备技能系列6:软件安装部署是最基本的能力!
    一个测试老鸟对职业技术交流群的几点看法
    为什么你一直找不到工作:因为你什么都想学,什么都不会!
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12925915.html
Copyright © 2011-2022 走看看