Codeforces Round 1003 (Div. 4) - 题解
A - Skibidus and Amog’u
模拟
如题意,输出前 n − 2 n-2 n−2 个字符 + 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 bj−ai。由于限制 + 贪心策略,需找出 b j − a i ≥ a i − 1 b_j-a_i\geq a_{i-1} bj−ai≥ai−1 下最小的 b j − a i b_j-a_i bj−ai,即找出 b j ≥ a i − 1 + a i b_j\geq a_{i-1}+a_i bj≥ai−1+ai 下最小的 b j b_j bj. 将数组 b
排序,再二分搜索即可,可使用 lower_bound
.
对于可行(即 ≥ a i − 1 \geq a_{i-1} ≥ai−1的)的 a i a_i ai 与 b j − a i b_j-a_i bj−ai,选择较小者作为更新后的 a i a_i ai,若二者均不可行(即都 < a i − 1 <a_{i-1} <ai−1),则无法构成,输出 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(n−i+1)×ai=na1+(n−1)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