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";
    }
}
posted @ 2024-10-12 16:33  udiandianis  阅读(24)  评论(0)    收藏  举报