ZZJC新生训练赛第七场题解

udiandianis / 2024-11-07 / 原文

难度分类(同一难度下按字典序上升)

  • 入门: C
  • 简单: G, D
  • 中等: E, H, F, A
  • 困难: B

C-解题思路

数一下每个字母的数量看是不是偶数就可以得到答案。

C-代码实现

#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;

    std::vector<int> c(26);
    for (auto ch: s) {
        c[ch - 'a']++;
    }

    int f = 1;
    for (auto x: c) {
        if (x % 2) {
            f = 0;
            break;
        }
    }

    if (f) {
        std::cout << "Yes";
    } else {
        std::cout << "No";
    }
}

G-解题思路

直接用梯形面积公式计算即可,注意数据范围, \((a+b)*h\) 的最大值已经来到了 \(2e19\),这已经超出了long long甚至unsigned long long的范围,然而题目保证了 \(h\) 是偶数,而 \(1e19\) 是在unsigned long long范围内的,因此只需要把 \(h/2\) 放前面算就行了,即 \(h/2*(a+b)\) 。(也可以用int128计算结果后强转unsigned long long输出,Python虽然内置高精度,但是本题多测卡掉了)

G-代码实现

#include <bits/stdc++.h>

using u64 = unsigned long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    
    int t;
    std::cin >> t;

    while (t--) {
        u64 a, b, h;
        std::cin >> a >> b >> h;

        std::cout << h / 2 * (a + b) << "\n";
    }
}

D-解题思路

按照题意模拟即可,本题卡了ceil,需要用(a+b-1)/b进行向上取整,注意数据范围,本题需要long long

D-代码实现

#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;

    i64 ans;
    std::cin >> ans;
    for (int i = 1; i < n; i++) {
        int x;
        std::cin >> x;

        if (ans >= x) {
            ans = (ans + x - 1) / x;
        } else {
            ans = ans + x;
        }
    }

    std::cout << ans;
}

E-解题思路

按照题意模拟即可,看谁的牌先为空就输出答案。

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);
    
    std::string sa, sb, sc;
    std::cin >> sa >> sb >> sc;

    std::map<char, std::string> mp{{'a', sa}, {'b', sb}, {'c', sc}};
    char ans = 'a';
    while (!mp[ans].empty()) {
        char c = mp[ans].front();
        mp[ans].erase(mp[ans].begin());
        ans = c;
    }

    std::cout << (char)toupper(ans);
}
# Python写水题的简短代码可以学习一下
dic = {'a': list(input()), 'b':list(input()), 'c':list(input())}
c = 'a'
while dic[c]:
    c = dic[c].pop(0)
print(c.upper())

H-解题思路

范围相当小,纯暴力计算答案即可。

H-代码实现

#include <bits/stdc++.h>

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int n, ans = 1e9;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }

    for (int i = -100; i <= 100; i++) {
        int t = 0;
        for (int j = 0; j < n; j++) {
            t += (a[j] - i) * (a[j] - i);
        }
        ans = std::min(ans, t);
    }

    std::cout << ans;
}

F-解题思路

范围相当小,纯暴力计算答案即可,注意第三个值可以用前两个值直接算出来,不要三层循环(不要将值放到容器中统计长度,这样会mle)。

F-代码实现

#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 k, s, cnt = 0;
    std::cin >> k >> s;
    
    for (int x = 0; x <= k; x++) {
        for (int y = 0; y <= k; y++) {
            if (0 <= s - x - y && s - x - y <= k) {
                cnt++;
            }
        }
    }

    std::cout << cnt;
}

A-解题思路

因为不会同时不喜欢1-9,所以其实最终的答案是不会大于10n的,而n的范围是1e4,所以从n开始+1遍历就行了。

A-代码实现

#include <bits/stdc++.h>

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int n, k;
    std::cin >> n >> k;

    std::set<char> st;
    for (int i = 0; i < k; i++) {
        char ch;
        std::cin >> ch;

        st.insert(ch);
    }

    int ans = n;
    while (1) {
        int f = 0;
        std::string s = std::to_string(ans);
        for (auto ch: s) {
            if (st.count(ch)) {
                f = 1;
                break;
            }
        }
        if (f) {
            ans++;
        } else {
            std::cout << ans;
            break;
        }
    }
}
# Python写水题的简短代码可以学习一下
n, k = map(int, input().split())
d = set(input().split())
ans = n
while set(str(ans)) & d:
    ans += 1
print(ans)

B-解题思路

范围很小可以直接dfs爆搜,将符号插在每个数字间的情况全考虑一遍即可

B-代码实现

#include <bits/stdc++.h>

using i64 = long long;
i64 ans = 0;


void dfs(std::string s, int pos, i64 num, i64 sum) {
    if(pos == s.size()) {  // pos是考虑了多少个数字,如果等于size说明全考虑了
        ans += sum + num;
        return;
    }

    // num是最新的加号后面的那个数字,sum是前面所有数字运算后的和
    dfs(s, pos + 1,  num * 10 + (s[pos] - '0'), sum); // 不插入加号
    dfs(s, pos + 1, s[pos] - '0', sum + num);  // 插入加号
}

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    std::string s;
    std::cin >> s;

    dfs(s, 1, s[0] - '0', 0);

    std::cout << ans << "\n";
}