586 字
2 分钟
Atcoder_Beginner_Contest_464(A~D题)

题目链接:https://atcoder.jp/contests/abc464/tasks
A - Decisive Battle
遍历字符串然后计数字符和,比较并输出最大的字符即可。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int cntE, cntW = 0; string s; cin >> s; for(auto it : s){ if(it == 'E') cntE++; else cntW++; } cout << ((cntE > cntW) ? "East" : "West") << endl;}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; //cin >> _; while (_--) { solved(); } return 0;}B - Crop
因为边界的都会被去除,题意可以转化为找到最大的含有字符的矩阵。我们找到这个矩阵边界四个端点,然后遍历输出这个矩阵即可。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
char grid[60][60];
void solved() { int H, W; cin >> H >> W; int WideMax = 0, LenMax = 0; int WideMin = 51, LenMin = 51; for(int i = 1; i <= H;i++){ for(int j = 1; j <= W;j++){ cin >> grid[i][j]; if(grid[i][j] == '#'){ WideMax = max(WideMax, j); LenMax = max(LenMax, i); WideMin = min(WideMin, j); LenMin = min(LenMin, i); } } } for(int i = LenMin; i <= LenMax;i++){ for (int j = WideMin; j <= WideMax;j++){ cout << grid[i][j]; } cout << endl; }}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; //cin >> _; while (_--) { solved(); } return 0;}C - Plumage Palette
这题我们不需要每次都计算当天对应的颜色总数,我们只需要在遍历到天数时更新这个总数,然后输出即可。
我们用一个二维数组记录每天会发生变化的颜色(变成),用记录该颜色的总数,然后在遍历天数的时候根据和的数量来更新颜色总数。当进行颜色变换后如果为,那么总数就减一,如果原来为,那么就加一。
这里的遍历记录当天颜色变化的实际上只增加了常数()级的复杂度。这是因为的总数虽然为,但是每次循环时并不会取满这次,只有当完全遍历完天数时才会循环满这次。所以这里的时间复杂度为,完全可以通过本题。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int N, M; cin >> N >> M; vector<vector<pii>> event(M + 1); vector<int> cnt(N + 1, 0); for(int i = 1; i <= N; i++){ int A, D, B; cin >> A >> D >> B; cnt[A]++; event[D].push_back({A, B}); } int kind = 0; for(int c = 1; c <= N; c++){ if(cnt[c] > 0) kind++; } for(int i = 1; i <= M; i++){ for(auto [A, B] : event[i]){ cnt[A]--; if(cnt[A] == 0) kind--; if(cnt[B] == 0) kind++; cnt[B]++; } cout << kind << endl; }}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); solved(); return 0;}D - Celester
这题是典型的线性,后面的操作不影响前面的结果。
我们可以定义和分别为前天的最优幸福值。那么当前的最优幸福值就可以由前面的继承或者修改得到。我这里定义为第天是该字符的代价(不变就是,改变就是减去)。
那么对于来说,它就可以由或者继承得来,因为无论这里的前一天是还是,当天都是,无法满足加幸福值的条件。
对于来说,它就可以由或者得来。这里当前一天为时,就满足了前后的条件,就可以加。
所以状态转移方程就是
我们每次更新时都在前一天选或者中取了最优方案,因此这种方法可以保证最终最优解出现在或者其中之一。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int N; cin >> N; string s; cin >> s; vector<ll> X(N + 1); vector<ll> Y(N); for(int i = 1; i <= N;i++) cin >> X[i]; for(int i = 1; i < N;i++) cin >> Y[i];
auto cost = [&](int i, int statue) -> ll { char c = (statue ? 'S' : 'R'); return (s[i - 1] == c ? 0 : -X[i]); };
ll dpR = cost(1, 0); ll dpS = cost(1, 1); for(int i = 2; i <= N;i++){ ll ndpR = max(dpR + cost(i, 0), dpS + cost(i, 0)); ll ndpS = max(dpR + Y[i - 1] + cost(i, 1), dpS + cost(i, 1)); dpR = ndpR; dpS = ndpS; } cout << max(dpR, dpS) << endl;}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cin >> _; while (_--) { solved(); } return 0;}Atcoder_Beginner_Contest_464(A~D题)
https://mkrari.cn/posts/abc_464/