「题解」写点 Codeforces 之 0x00
2024/11/8大约 3 分钟
CF2023B
Info
给定一个正整数 和数列长度为 , 为奇数的数列 ,将其划分为 个长度都为奇数的子序列,记划分后的第 个子序列 。定义对于数列 , 表示其中位数。令 ,求一种划分方式使得 。
Solution
显然划分方式不唯一。若我们把每一个给出的序列都划分为三个长度为奇数的子序列 。由于对于任意 ,有 恒成立,故 恒成立。只要令 ,则 成立,得到一种划分方案。
记 的首项在 中的位置为 ,则枚举 , 。若存在一种划分满足题目条件,则输出此划分,否则输出 。
Code
void solve() {
int n, k;
cin >> n >> k;
if (n == 1) {
cout << 1 << '\n' << 1 << '\n';
return;
}
int l = k, r = k + 1;
bool ok = false;
while (l >= 1 and r <= n) {
if ((r - l) % 2 and (l - 1) % 2 and (n - r + 1) % 2) {
ok = true;
break;
}
l -= 1;
r += 1;
}
if (ok) {
cout << 3 << '\n' << 1 << ' ' << l << ' ' << r;
} else {
cout << -1;
}
cout << '\n';
}CF2030B
Info
给定一个正整数 ,求一个由 和 组成的字符串 ,使得全由 组成的子序列与存在 的子序列的数目之差最小。
Solution
只要 中存在 ,那么存在 的子序列的个数至少为 ,为了使得全由零组成的子序列的个数与存在 的子序列的个数接近,显然令 的个数为 ,即存在 个全 子序列,有我们期望的值最小。
Code
void solve() {
int n;
cin >> n;
cout << 1;
for (int i = 1; i < n; i ++)
cout << 0;
cout << '\n';
}CF2027B
Info
定义斯大林排序为函数 , 为任意数组。对于一个数组 ,若对数组 的任意子数组(数组元素连续)进行任意次斯大林排序,最终操作后的数组 单调递减,那么认为这个数组是脆弱的。
给定一个具有 个元素的数组 ,移除 个元素使 变成一个脆弱的数组。求 的最小值。
Solution
我们首先考察对于一个数组 如何变化为 。若 ,那么显然只需要对 中的每一个逆序对加上一个顺序对的结构(即 ,这样就消除了一个顺序对,让 的递减程度变高)进行斯大林排序,直到数组递减即可。
那么考虑对于数组 中的任意一个元素 ,删去 个元素使得 ,就能使得 变成一个脆弱的数组。
只需要求出每一个 ,并统计其最小值即可。
Code
void solve() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i ++)
cin >> a[i];
int ans = n;
for (int i = 0; i < n; i ++) {
int stl = i;
for (int j = i + 1; j < n; j ++) {
if (a[j] > a[i])
stl ++;
}
ans = min(ans, stl);
}
cout << ans << '\n';
}