雅礼 2023.12.27 习题课记录
雅礼 2023.12.27 习题课记录
前言
这一场罚时多,都是一些低级错误。
好吧全都是水题。
水题(只放代码)
莫诺卡普参加了一场编程比赛,其中包括 个问题,从
A
到Z
命名。问题按难度排序。此外,已知莫诺卡普可以在 分钟内解决问题A
,在 分钟内解决问题B
,,在 分钟内解决问题Z
。比赛结束后,你发现了他的比赛记录 - 一个由大写拉丁字母组成的字符串,其中第 个字母表示莫诺卡普在比赛的第 分钟时正在解决的问题。如果莫诺卡普总共花费了足够的时间来解决一个问题,他就解决了它。请计算莫诺卡普在比赛期间解决的问题数量。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
int n;
string s;
int a[kMaxN];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
for (int i = 1; i <= 26; ++ i) {
a[i] = 0;
}
cin >> n >> s;
for (int i = 0; i < s.size(); ++ i) {
++ a[s[i] - 'A' + 1];
}
int ans = 0;
for (int i = 1; i <= 26; ++ i) {
if (a[i] >= i) {
++ ans;
}
}
cout << ans << '\n';
}
return 0;
}
C - Preparing for the Contest(CF1914B)
输出一个长度为 的序列,使序列中后一个数比前一个数大的次数为 。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
int n, k;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
cin >> n >> k;
for (int i = 1; i <= (!k? 0 : k); ++ i) {
cout << i << ' ';
}
int ans = 1;
for (int i = n; ans <= (!k? n : n - k); -- i) {
cout << i << ' ';
++ ans;
}
cout << '\n';
}
return 0;
}
E - Rating Increase(CF1913A)
给定 ,求任意一种可能的 ,其中 且 无前导零。如果无解,请输出 。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
string s;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
cin >> s;
bool f = 0;
for (int i = 0; i < s.size() - 1; ++ i) {
if (stoi(s.substr(0, i + 1)) < stoi(s.substr(i + 1)) && s[i + 1] != '0') {
cout << s.substr(0, i + 1) << ' ' << s.substr(i + 1) << '\n';
f = 1;
break;
}
}
if (!f) {
cout << -1 << '\n';
}
}
return 0;
}
高级水题
F - Swap and Delete(CF1913B)
有一个只含 和 的字符串 ,你可以对它进行如下两种操作:耗费一个金币,从 中删除 个字符,将 中任意两字符互换位置(免费)。定义一个字符串 是美的代表对于所有满足 的 , 。你可以进行任意多次操作,假设 修改后变为了 ,问最少花费多少金币能使最终得到的 是美的。
首先,我们统计 的 和 的数量,然后遍历 。如果 串为 ,则在另一个字符串填 ,否则填 。当没有办法继续填时输出 的长度减去另一个字符串的长度。因为此时后面不管怎么填一定会有相同的。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
string s;
auto C() {
int zr = 0, one = 0;
for (int i = 0; i < s.size(); ++ i) {
s[i] == '0'? ++ zr : ++ one;
}
return make_pair(one, zr);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
cin >> s;
int a = C().first, b = C().second;
string s2 = "";
for (int i = 0; i < s.size(); ++ i) {
if (s[i] == '0') {
if (a > 0) {
s2 += "1";
-- a;
} else {
break;
}
} else {
if (b > 0) {
-- b;
s2 += "0";
} else {
break;
}
}
}
cout << s.size() - s2.size() << '\n';
}
return 0;
}
D - Quests(CF1914C)
有 个任务,在完成 任务时, 之前的所有任务都必须完成。同时,可以多次完成某个任务。总共可以做 次任务,第一次完成 任务的贡献为 ,后面完成 任务的贡献为 ,求最大贡献。
当 个次数全部用于前 个任务时,当且仅当每个任务都至少做过一遍,且剩余的次数全部用于前 个任务中 花费最大的任务,取到当前情况的最大花费。
最优的策略是选 中最大的 ,选 次,然后把答案加起来。
前缀和预处理。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 2e5 + 20, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
int n, k;
struct node {
ll a, b;
} a[kMaxN];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
cin >> n >> k;
for (int i = 0; i < n; ++ i) {
cin >> a[i].a;
}
for (int i = 0; i < n; ++ i) {
cin >> a[i].b;
}
ll p = 0, cnt = 0, maxa = 0, ans = 0;
for (int i = 0; i < n && i != k; ++ i) {
maxa = max(maxa, a[i].b), cnt += a[i].a;
p = (k - i - 1) * maxa + cnt, ans = max(ans, p);
}
cout << ans << '\n';
}
return 0;
}
A - Three Activities(CF1914D)
给定三个数组 ,找三个互不相同的整数 ,使得 的值最大。
额,出这种题很无聊,洛谷都评了个黄(CSPJ T3 难度左右)。除了码量多了一点还有什么难度?看了洛谷题解,还有用 dp 的……
直接搜索即可。先按照从大到小排好序,然后搜索时搜索前 大的每种排列,取最大值。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
int n, ans = 0;
bool vis[kMaxN];
struct node {
int w, id;
} a[kMaxN], b[kMaxN], c[kMaxN];
bool cmp(node a, node b) {
return a.w > b.w;
}
void S(int k, int sum) {
if (k > 3) {
ans = max(ans, sum);
return;
}
for (int i = 1; i <= 3; ++ i) {
if (k == 1) {
if (!vis[a[i].id]) {
vis[a[i].id] = 1;
S(k + 1, sum + a[i].w);
vis[a[i].id] = 0;
}
}
if (k == 2) {
if (!vis[b[i].id]) {
vis[b[i].id] = 1;
S(k + 1, sum + b[i].w);
vis[b[i].id] = 0;
}
}
if (k == 3) {
if (!vis[c[i].id]) {
vis[c[i].id] = 1;
S(k + 1, sum + c[i].w);
vis[c[i].id] = 0;
}
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
mtest {
cin >> n;
for (int i = 1; i <= n; ++ i) {
cin >> a[i].w;
}
for (int i = 1; i <= n; ++ i) {
cin >> b[i].w;
}
for (int i = 1; i <= n; ++ i) {
cin >> c[i].w;
}
for (int i = 1; i <= n; ++ i) {
a[i].id = b[i].id = c[i].id = i;
}
sort(a + 1, a + n + 1, cmp);
sort(b + 1, b + n + 1, cmp);
sort(c + 1, c + n + 1, cmp);
memset(vis, 0, sizeof vis);
ans = 0;
S(1, 0);
cout << ans << '\n';
}
return 0;
}
正常题
G - Game with Multiset(CF1913C)
你有一个空的多重集,你需要处理若干下列询问:ADD :加入一个数值为 的元素到该多重集,GET :判断是否存在一个该多重集的子集,使得这个子集的所有元素之和等于 。
这是唯一一道正常题。
首先我们预处理 ,存在一个 map
里,。然后再开另一个 map
,名为 mp2
。
- ADD
将 的元素 即可。(++ mp2[mp[v]
)
- GET
我们从 开始遍历 。每一次 不为 且 时,如果 的个数不为 ,将 减去 。
如果 最后为 ,输出 YES
,否则输出 NO
。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;
using ll = long long;
#define mtest for (cin >> t; t; -- t)
const int kMaxN = 1e5 + 10, kInf = (((1 << 30) - 1) << 1) + 1;
const ll kLInf = 9.22e18;
ll m;
map<ll, ll> mp, mp2;
void init() {
for (ll i = 0; i < 30; ++ i) {
mp[i] = (1ll << i);
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
cin >> m;
for (; m; -- m) {
int op, v;
cin >> op >> v;
if (op == 1) {
++ mp2[mp[v]];
} else {
for (ll i = 29; i >= 0; -- i) {
if (v != 0 && v >= mp[i]) {
if (mp2.count(mp[i])) {
v -= min(v / mp[i], mp2[mp[i]]) * mp[i];
}
}
}
cout << (!v? "YES" : "NO") << '\n';
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效