ZZJC新生訓練賽第七場題解

udiandianis發表於2024-10-21

難度分類(同一難度下按字典序上升)

  • 入門: 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";
}

相關文章