CF1873(Div. 4) 题解 (A to E)

发布时间 2023-10-04 14:53:11作者: cyf1208

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;
}