【寒假复健Day5】Codeforces Round 1003 (Div. 4) - 题解

Codeforces Round 1003 (Div. 4) - 题解

Codeforces Round 1003 (Div. 4)

A - Skibidus and Amog’u

模拟

​ 如题意,输出前 n − 2 n-2 n2 个字符 + i 即可。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
#include<bits/stdc++.h>

using namespace std;
int main() {
   
    cin.tie(NULL)->sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
   
        string str;
        cin >> str;
        cout << str.substr(0, str.size() - 2) << "i\n";
    }
}

B - Skibidus and Ohio

思维

​ 我称之为 “点燃” 类,出题思路常用于简单题。一旦 出现相邻两个字符串相同,其中一个被删除,字符串长度 − 1 -1 1,另一个变为左侧或右侧字符,则必然与该侧字符一起再次达成 “相邻两个字符串相同” 的条件,循环往复,直至只剩一个字符。

​ 判断字符串中是否存在相邻两字符相同,若存在则输出 1 1 1,反之为字符串长度。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
#include<bits/stdc++.h>

using namespace std;
int main() {
   
    cin.tie(NULL)->sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
   
        string str;
        cin >> str;
        int res = str.length();
        for (int i = 1; i < res; i++)
            if (str[i] == str[i - 1]) res = 1;
        cout << res << '\n';
    }
}

C - Skibidus and Fanum Tax

贪心,排序,二分

​ 从左往右考虑,当前数变得越小,则后续 “选择余地” 只会越大,文绉绉地说,这叫贪心的 “决策包容性”。故我们依次考虑每个 a i a_i ai 选择让其尽可能小。

​ 对于 a i a_i ai,若进行操作,则变为 b j − a i b_j-a_i bjai。由于限制 + 贪心策略,需找出 b j − a i ≥ a i − 1 b_j-a_i\geq a_{i-1} bjaiai1 下最小的 b j − a i b_j-a_i bjai,即找出 b j ≥ a i − 1 + a i b_j\geq a_{i-1}+a_i bjai1+ai 下最小的 b j b_j bj. 将数组 b 排序,再二分搜索即可,可使用 lower_bound.

​ 对于可行(即 ≥ a i − 1 \geq a_{i-1} ai1的)的 a i a_i ai b j − a i b_j-a_i bjai,选择较小者作为更新后的 a i a_i ai,若二者均不可行(即都 < a i − 1 <a_{i-1} <ai1),则无法构成,输出 NO。反之构造完毕,则输出 YES

  • 时间复杂度: O ( m + n log ⁡ m ) O(m+n\log{m}) O(m+nlogm)
  • 空间复杂度: O ( n + m ) O(n+m) O(n+m)
#include<bits/stdc++.h>

using namespace std;
const int N = 2e5;
int a[N], b[N];

int main() {
   
    cin.tie(NULL)->sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
   
        int n, m, last = INT_MIN + 1, res = 1;
        cin >> n >> m;
        for (int i = 0; i < n; i++) cin >> a[i];
        for (int i = 0; i < m; i++) cin >> b[i];
        sort(b, b + m);
        for (int i = 0; i < n; i++) {
   
            int tar = lower_bound(b, b + m, a[i] + last) - b;
            if (tar == m) {
   
                if (a[i] < last) res = 0;
                last = a[i];
            } else {
   
                if (a[i] < last) last = b[tar] - a[i];
                else last = min(a[i], b[tar] - a[i]);
            }
        }
        cout << (res ? "YES\n" : "NO\n");
    }
}

D - Skibidus and Sigma

搜索

​ 这是一个经典贪心策略的弱化版(一开始我误理解为下面的改造版)。

​ 其答案为 ∑ i = 1 n ( n − i + 1 ) × a i = n a 1 + ( n − 1 ) a 2 + ⋯ + a n \sum_{i=1}^n (n-i+1)\times a_i=na_1+(n-1)a_2+\cdots+a_n i=1n(ni+1)×ai=na1+(n1)a2++an,用 v i v_i vi 表示第 i i i 个数组, s i s_i si 表示 v i v_i vi 的和。若数组向左移动 1 1 1 单位,则该数组每个元素系数 + 1 +1 +1,整体和 + s i +s_i +si,反之向右移动 1 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值