ZZJC新生训练赛第三场题解
链接:https://ac.nowcoder.com/acm/contest/92885
密码:sfjo21fe35t
难度分类(同一难度下按字典序上升)
- 入门: B, D
- 简单: G, C
- 中等: A, F, H
- 困难: E
B-解题思路
根据题意可知扫描一次 \(S\) ,遇到 "\(.\)" 不输出,否则输出即可。
B-代码实现
#include <bits/stdc++.h>
int main() {
// 关同步加快读入(频繁输入输出时可以加快速度,这题没什么用)
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::string s;
std::cin >> s;
// 遍历s中的内容判断是不是"."
for (auto ch: s) {
if (ch != '.') {
std::cout << ch;
}
}
}
# Python在对字符串进行简单处理很有优势,这种超级水题可以考虑一下用Python
print(''.join(input().split('.'))) # 以"."为分割符分割输入的字符串,用空拼接
D-解题思路
简单的归纳总结即可发现答案和 \(A\) 与 \(B\) 差值的奇偶性有关,注意要特别考虑 \(A\) 与 \(B\) 相等的情况。
D-代码实现
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int a, b;
std::cin >> a >> b;
if (a == b) {
std::cout << 1;
} else if ((a - b) % 2) {
std::cout << 2;
} else {
std::cout << 3;
}
}
G-解题思路
按照题意纯模拟即可。
G-代码实现
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::string s, ans = "";
std::cin >> s;
for (int i = 0; i < s.size(); i++) {
if (s[i] != 'B') { // 只要不是B就加上这个字符
ans += s[i];
} else if (!ans.empty()) { // 不是空串的时候遇到B就删除最后一个字符
ans.pop_back();
}
}
std::cout << ans;
}
C-解题思路
可以使用贪心的思想来解决,每次都输出当前允许的最大的值。
C-代码实现
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n;
std::cin >> n;
std::vector<int> ans;
while (n) {
int p = 1, t = 0;
while (p * 3 <= n) { // 计算当前剩余的n中最多能是3的多少次
p *= 3;
t++;
}
n -= p;
ans.push_back(t);
}
std::cout << ans.size() << "\n";
for (auto x: ans) {
std::cout << x << " ";
}
}
A-解题思路
可以使用set对元素进行 \(O(logn)\) 的查询和删除,接下来模拟题意即可。
注意数据范围,本题需要开longlong。
A-代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n;
std::cin >> n;
std::set<i64> st;
for (int i = 0; i < n; i++) {
i64 x;
std::cin >> x;
if (st.count(x)) {
st.erase(x);
} else {
st.insert(x);
}
}
std::cout << st.size();
}
F-解题思路
纯暴力预处理出所有可能的情况,再快速判断存在即可。
F-代码实现
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n, m, l, q, t;
std::cin >> n;
std::set<int> a, b, c, d;
for (int i = 0; i < n; i++) {
std::cin >> t;
a.insert(t);
}
std::cin >> m;
for (int i = 0; i < m; i++) {
std::cin >> t;
b.insert(t);
}
std::cin >> l;
for (int i = 0; i < l; i++) {
std::cin >> t;
c.insert(t);
}
// 暴力预处理三个数字的和
for (auto ax: a) {
for (auto bx: b) {
for (auto cx: c) {
d.insert(ax + bx + cx);
}
}
}
std::cin >> q;
for (int i = 0; i < q; i++) {
std::cin >> t;
if(d.count(t)) { // set可以ologn判断存在与否
std::cout << "Yes" << "\n";
} else {
std::cout << "No" << "\n";
}
}
}
H-解题思路
先对所有的坐标排序,然后用双指针滑动窗口爽滑即可。
H-代码实现
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n, m;
std::cin >> n >> m;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end());
int l = 0, r = 0, ans = 0;
while (r < n) {
if (a[r] - a[l] < m) { // a[r] - a[l] 就是坐标的距离,题目指定左闭右开,因此不能取等于,与m比较进行左右区间的指针移动即可
r++;
} else {
l++;
}
ans = std::max(ans, r - l); // 对于每个窗口都更新一次最大值
}
std::cout << ans;
}
E-解题思路
首先要理解无限补贴的含义,它所指的其实是所有补贴加一起都不会超过一开始的预算 \(M\) 。
每个人的补贴越多,加一起的总花费就越多,这里满足二分的单调性,因此可以考虑二分答案,即给每个人一个可能的值mid,看这个mid能不能满足所有人的要求。
注意数据范围,本题需要开longlong。
E-代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
i64 n, m, maxn = 0;
std::cin >> n >> m;
std::vector<i64> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
maxn = std::max(maxn, a[i]);
}
int l = 0, r = maxn, res = 0; // 二分的左右边界初始化
while (l <= r) {
i64 mid = (l + r) / 2, sumn = 0;
for (auto x: a) { // 当以mid的补贴给每个人的时候,总的花费是多少,如果mid > x,也就是这个人不需要这么多补贴,则用花费为这个人本身需要的补贴价格
sumn += std::min(x, mid);
}
if (sumn <= m) { // 如果以mid为单人补贴的总花费小于预算,则可以提高单人补贴的价格
l = mid + 1;
res = mid;
} else {
r = mid - 1;
}
}
if (res < maxn) { // 最后只需要比较一下是不是每人都可以享受最高待遇
std::cout << res;
} else {
std::cout << "infinite";
}
}

浙公网安备 33010602011771号