zoukankan      html  css  js  c++  java
  • Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020

    1443A. Kids Seating

    题意: 给你一个整数n,现在你需要从编号 (1) ~ $4 ⋅ n (中选出)n(个编号使得这些编号之间)g c d ≠ 1$ ,不能整除。

    看了半天,发现只要满足 (起始点在 2 · n + 2,然后依次增加2) 即可

    void solve() {
        cin >> n;
        for (int i = 2 * n + 2; i <= 4 * n; i += 2) cout << i << " ";
        cout << endl;
    }
    
    for _ in range(int(input())):
    	n = int(input())
    	print(*[2*i+2*n+2 for i in range(n)])
    

    1443B. Saving the City

    题意:

    现在城市中有一些炸弹,但我们的拆弹专家知道如何引爆炸弹而不影响建筑(引爆时会使整个连续区间的炸弹都爆炸)。引爆一次炸弹需要 (a) 花费,而添加一个炸弹需要 (b) 花费。问怎么做才能使消费最小

    思路:

    由于任何地雷的激活都会炸毁整个地雷段,因此您可以立即用一系列地雷段替换输入字符串。 现在,我们有两个操作。 我们可以用硬币删除任何分段,或者将两个相邻的分段 ([l1,r1],[l2,r2] (r1 <l2))变成 (b⋅(l2-r1))的分段。 即,可以以 (2⋅a)(a +b⋅(l2-r1)) 的代价删除两个片段。 这意味着您需要在 (b⋅(l2-r1)≤a) 时合并两个段。 所以想到取到最小花费只需要遍历所有相邻的路段并检查这种情况。

    void solve() {
        int a, b; cin >> a >> b;
        string s; cin >> s;
        int i = 0, len = s.length();
        vector<pair<int, int>> v;
        while (i < len) {
            while (i < len && s[i] == '0') i++;
            int j = i;
            while (j < len && s[j] == '1') j++;
            if (i < len) v.push_back({i, j});
            i = j;
        }
        if (v.size() == 0)
            printf("0
    ");
        else {
            int ans = a;
            for (int i = 1; i < v.size(); i++) {
                ans += min((v[i].first - v[i - 1].second) * b, a);
            }
            printf("%d
    ", ans);
        }
    }
    

    1443C. The Delivery Dilemma

    题意:

    你需要点(n)个不同的菜,你有两种方式可以选择,一种是点外卖,花费(a_i) 时间,一种是自己拿,花费(b_i) 时间。你需要在最少的时间中弄完这(n) 个菜。

    思路:

    因为选择点外卖一直是需要人在家的(等价于点外卖一定是最大时间),那么根据贪心思想只需要统计自己拿的时间总和(此时需要自定义排序)

    // Author : RioTian
    // Time : 20/11/03
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 10;
    struct node {
        int x, y;
    } a[maxn];
    bool cmp(node a, node b) { return a.x < b.x; }
    ll _, n;
    void solve() {
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i].x;
        for (int i = 1; i <= n; ++i) cin >> a[i].y;
        sort(a + 1, a + 1 + n, cmp);
        int now = n, sum = 0;
        while (now >= 1) {
            if (a[now].x > sum + a[now].y) {
                sum += a[now].y;
                now--;
            } else
                break;
        }
        cout << max(a[now].x, sum) << '
    ';
    }
    int main() {
        // freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        cin >> _;
        while (_--) solve();
    }
    

    1443D. Extreme Subtraction

    思路:(来自比赛提示)

    问题看起来像是-检查是否有递增和递减的数组,它们在元素上的总和等于给定的数组。
    这个问题可以贪婪地解决。 让我们最大化递减数组的每个元素(我们称此数组为a,递增数组为b)。 假设初始数组为v,我们已经解决了长度为(i-1)的前缀的问题。 然后,对于元素a [i],必须满足(a [i]≤a[i-1])(v [i] -a [i]≥b[i-1])。 重写第二个不等式并与第一个不等式组合,我们得到(a [i]≤min(a [i-1],v [i] -b [i-1]))。 显然,通过构造最好采用(a [i] = min(a [i-1],v [i] -b [i-1]))

    void solve() {
        int n;
        cin >> n;
        vector<int> arr(n), last(n);
        int rem = 0;
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
        }
        int l = arr[0], r = 0;
        for (int i = 1; i < n; i++) {
            if (r > arr[i]) {
                cout << "NO
    ";
                return;
            }
            if (l + r < arr[i]) {
                r = arr[i] - l;
            } else {
                l = arr[i] - r;
            }
        }
        cout << "YES
    ";
    }
    

    E、F表示没怎么看懂题,待补状态。。。

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    优先队列
    Problem W UVA 662 二十三 Fast Food
    UVA 607 二十二 Scheduling Lectures
    UVA 590 二十一 Always on the run
    UVA 442 二十 Matrix Chain Multiplication
    UVA 437 十九 The Tower of Babylon
    UVA 10254 十八 The Priest Mathematician
    UVA 10453 十七 Make Palindrome
    UVA 10163 十六 Storage Keepers
    UVA 1252 十五 Twenty Questions
  • 原文地址:https://www.cnblogs.com/RioTian/p/13921286.html
Copyright © 2011-2022 走看看