[codeforces] 暑期训练之打卡题(三)
每个标题都做了题目原网址的超链接
Day21《Alphabetic Removals》
题意:
给定一个字符串,要求按照字典序按照出现的前后顺序删除 k 个字母
题解:
- 记录字符串中各个字母出现次数
- 删去字典序下前 k 个
代码注释会比较清楚,题解可能讲的有点模糊了
上板子:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int num[26] = { 0 }; int main() { int n, k; cin >> n >> k; string s; cin >> s; string t = s; sort(s.begin(), s.end());//按照字典序 a-z 排序 for (int i = 0; i < k; i++) { num[s[i] - 'a']++;//前k个字符都删除,记录其对应的字母的个数 } for (int i = 0; i < t.size(); i++) { if (num[t[i] - 'a']) num[t[i] - 'a']--;//按照出现次序删除字母 else cout << t[i];//该字母已无需删除 } return 0; }
Day22《Anti-Sudoku》
题意:
更改一个数独使其满足:每行、列、3*3的方格内,至少有两个元素相等
题解:
更改一个数为另一个数就行
上板子:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 7; int cnt[N]; int main() { int t; cin >> t; while (t--) { for (int i = 0; i < 9; i++) { string s; cin >> s; for (char& c : s) if (c == '1')//随便一个1~9的数字变成1~9的另一个数字即可 c = '2'; cout << s << endl; } } }
Day23《Boats Competition》
题意:
给定 n 个数构成的数组, 让我们自定义一个数 s , 使得对于任选 ai 与 aj(i≠j),满足 ai+aj=s 的组合尽可能多,输出个数
题解:
一点闲话:
- 这个题关键的地方就是注意到数据范围都很小,这就启示我们可以暴力。
- 想到了用map<int,int>记录 s 与 s 的出现次数,但是没有想到怎么合适地处理循环问题
正经题解:记录给出的数组中每个数字出现的次数(代码注释较为详细)
上板子:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1E2 + 10;//n最大只有50, wi最大也只有50, 所以s最大不会超过100 int a[N], b[N]; //a数组存放n个数据(可以不要), b数组存放为x的值有多少个 int main() { int t; cin >> t; while (t--) { memset(b, 0, sizeof b); int n; cin >> n; for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), b[a[i]]++; int ans = 0; for (int k = 2; k <= 2 * n; ++k) { int cnt = 0; //s=k时的结果数量 for (int i = 1; i <= k / 2; ++i) { //避免重复只枚举前一半即可 if (b[i] && b[k - i] && i != k - i) { //要避免取到相同的数字情况 int temp = min(b[i], b[k - i]); cnt += temp; } } if ((k & 1) == 0) cnt += b[k >> 1] >> 1; //是偶数, 可能由相同数字组成 ans = max(ans, cnt); } cout << ans << endl; } return 0; }