CF1873(Div. 4) 题解 (A to E)
A Short Sort 题解
题目大意
给定一个长度为 \(3\) 、由 \(a,b,c\) 组成的字符串,问可以不变或交换两个字符是的变为 \(\texttt{abc}\)。
解题思路
由于大小固定,所以预处理可行的字符串(仅包含 \(\texttt{abc acb bac cba}\))即可。
代码
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t--) {
string s;
cin >> s;
if(s == "abc" || s == "acb" || s == "bac" || s == "cba") {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
return 0;
}
B Good Kid 题解
题目大意
给定长度为 \(n\) 的数列 \(\{a_i\}\),求 \(\max\limits_{i\in[1,n]}\left\{\left(i+1\right)\times\left(\prod\limits_{j\in[1,n],j\neq i}{j}\right)\right\}\)。
解题思路
直接模拟即可。
代码
#include<bits/stdc++.h>
using namespace std;
int a[10];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t--) {
int n, sum = 1, ans = 0;
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
for(int i = 1; i <= n; i++) {
sum = 1;
for(int j = 1; j <= n; j++) {
sum *= (j == i ? a[j] + 1 : a[j]);
}
ans = max(ans, sum);
}
cout << ans << '\n';
}
return 0;
}
C Target Practice 题解
题目大意
有一个正方形且边长为 \(10\) 的靶子,从外到内点数分别是 \(1\) 至 \(5\)。如图所示:
给定 Vlad 的射靶情况,例如:
X.........
..........
.......X..
.....X....
......X...
..........
.........X
..X.......
..........
.........X
X
表示 Vlad 射中的地方,求他的点数和。
解题思路
很水的一道模拟题。
我们找一下规律,对于一个坐标为 \(\left(i,j\right)\) 的点,则他的点数 \(f(i,j) = \begin{cases}
\min\{i,j\} & i\le5,j\le5 \\
\min\{i,11-j\} & i\le5,j>5 \\
\min\{11-i,j\} & i>5,j\le5 \\
\min\{11-i,11-j\} & i>5,j>5 \\
\end{cases}\),整合一下便是 \(f(i,j)=\min\{i,j,11-i,11-j\}\)。
代码
#include<bits/stdc++.h>
using namespace std;
char c[15][15];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t--) {
int cnt = 0;
for(int i = 1; i <= 10; i++) {
for(int j = 1; j <= 10; j++) {
cin >> c[i][j];
if(c[i][j] == 'X') {
cnt += min({i, j, 11 - i, 11 - j});
}
}
}
cout << cnt << '\n';
}
return 0;
}
D 1D Eraser 题解
题目大意
给定一个由 \(\texttt{W}\) 和 \(\texttt{B}\) 字符串 \(s\),每一次操作可以选任意一段长度为 \(k\) 的连续区间 \([l,r]\) 里所有元素都变为 \(\texttt{W}\)。
问至少需要几次操作才能使所有元素均为 \(\texttt{W}\)。
解题思路
枚举左端点 \(l\),如果 \(s_l\) 为 \(\texttt{B}\),则需要一次操作使得 \(s_l,s_{l+1},\cdots,s_{l+k-1}\) 均变为 \(\texttt{W}\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, k;
char a[N];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t--) {
int cnt = 0;
cin >> n >> k >> a;
int i;
for(i = 0; i < n - k + 1; ) {
if(a[i] == 'B') {
++cnt;
for(int t = 1; t <= k; t++) {
a[i] = 'W';
++i;
}
} else {
++i;
}
}
for(; i < n; i++) {
if(a[i] == 'B') {
++cnt;
break;
}
}
cout << cnt << '\n';
}
return 0;
}
E Building an Aquarium 题解
题目大意
给定 \(n\) 个柱子,每个柱子的高度为 \(a_1,a_2,\cdots,a_n\)。现往里头注入不大于 \(x\) 的水,对于每个单位的水,如果它两边的柱子高度比它矮,它将会流下去。
问水的最低深度的最大值 \(h\)。
解题思路
经典的二分。
由于水量不超过 \(x\),所以 \(h\) 一定小于 \(\max\limits_{i\in [1,n]}\{a_i\}+x\)。从而把 \(h\) 在 \([1,\max\limits_{i\in [1,n]}\{a_i\}+x]\) 中二分即可。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, x, a[N];
inline bool check(int xx) {
int cnt = 0;
for(int i = 1; i <= n; i++) {
cnt += (a[i] < xx ? xx - a[i] : 0);
}
return cnt <= x;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t--) {
int maxi = -1, ans = 0;
cin >> n >> x;
for(int i = 1; i <= n; i++) {
cin >> a[i];
maxi = max(maxi, a[i]);
}
int l = 1, r = maxi + x;
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
cout << ans << '\n';
}
return 0;
}