ZZJC新生訓練賽第十八場題解

udiandianis發表於2024-11-25

連結:https://www.nowcoder.com/acm/contest/97429
密碼:gar615gdsr

難度分類

  • 題目分值決定

A-解題思路

除一下比較分數大小即可

A-程式碼實現

a, b = map(int, input().split())
x, y = map(int, input().split())
if a / b > x / y:
    print(">")
elif a / b == x / y:
    print("=")
else:
    print("<")

B-解題思路

已經固定矩陣大小,列舉分界線後遍歷即可

B-程式碼實現

f = 1
g = []
for i in range(9):
    g.append(list(map(int, input().split())))
    if len(set(g[i])) != 9:
        f = 0
for x in [0, 3, 6]:
    for y in [0, 3, 6]:
        st = set()
        for i in range(3):
            for j in range(3):
                st.add(g[x + i][y + j])
        if len(st) != 9:
            f = 0 
if f:
    print("Valid")
else:
    print("Invalid")

C-解題思路

對n取餘除3直到n是0即可

C-程式碼實現

n = (int(input()))
ans = ""
while n > 0:
    ans = str(n % 3) + ans
    n //= 3
print(ans)

D-解題思路

看看每一天用哪種方式更划算然後求和即可

D-程式碼實現

n, c = map(int, input().split())
a = list(map(int, input().split()))
dp = [a[0]] * n
for i in range(1, n):
    dp[i] = min(dp[i - 1] + c, a[i])
print(sum(dp))

E-解題思路

算一下中間過程中會扣除的最大生命值即可,注意最後要+1保證是正數

E-程式碼實現

n = int(input())
a = list(map(int, input().split()))
ans = pre = 0
for i in a:
    pre += i
    ans = min(ans, pre)
print(abs(ans) + 1)

F-解題思路

雙指標誰小優先選誰即可

F-程式碼實現

s = input()
t = input()
 
i, j = 0, 0
n, m = len(s), len(t)
ans = []
 
while i < n and j < m:
    if s[i] <= t[j]:
        ans.append(s[i])
        i += 1
    else:
        ans.append(t[j])
        j += 1
 
if i < n:
    ans.append(s[i:])
if j < m:
    ans.append(t[j:])
 
print("".join(ans))

G-解題思路

按照截止排序,看完成時間會不會和開始時間有交叉

G-程式碼實現

#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::vector<std::array<int, 2>> dt(n);
    for (int i = 0; i < n; i++) {
        std::cin >> dt[i][0] >> dt[i][1];
    }

    std::sort(dt.begin(), dt.end());

    i64 sum = 0;
    for (auto [d, t]: dt) {
        sum += t;
        if (sum > d) {
            std::cout << "No\n";
            return 0;
        }
    }
    std::cout << "Yes\n";
}

H-解題思路

中位數附近就是最小值

H-程式碼實現

#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::vector<int> x(n);
    for (int i = 0; i < n; i++) {
        std::cin >> x[i];
    }

    std::sort(x.begin(), x.end());

    i64 ave1 = x[n / 2], ave2 = x[n / 2 + 1], ans1 = 0, ans2 = 0;
    for (int i = 0; i < n; i++) {
        ans1 += abs(ave1 - x[i]);
        ans2 += abs(ave2 - x[i]);
    }

    std::cout << std::min(ans1, ans2);
}

I-解題思路

求卡特蘭數

I-程式碼實現

#include <bits/stdc++.h>

using i64 = long long;
const int N = 1e6 + 10;
const int MOD = 1e9 + 7;

std::vector<i64> fac(N + 1, 1), invfac(N + 1, 1);

i64 ksm(i64 a, i64 n, i64 mod) {
    i64 res = 1;
    a = (a % mod + mod) % mod;
    while (n) {
        if (n & 1) {
            res = (a * res) % mod;
        }
        a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}

void init(int n) {
    fac[0] = 1;
    for (int i = 1; i <= n; i++) {
        fac[i] = fac[i - 1] * i % MOD;
    }
    invfac[n] = ksm(fac[n], MOD - 2, MOD);
    for (int i = n - 1; i >= 0; i--) {
        invfac[i] = invfac[i + 1] * (i + 1) % MOD;
    }
}

i64 C(int n, int m) {  // 組合數
    if (m > n || m < 0) {
        return 0;
    }
    return fac[n] * invfac[m] % MOD * invfac[n - m] % MOD;
}

i64 A(int n, int m) {  // 排列數
    if (m > n || m < 0) {
        return 0;
    }
    return fac[n] * invfac[n - m] % MOD;
}

// n 對括號的合法匹配數,有 n 個節點的二叉樹的種類數
// 從對角線下方走到對角線的路徑數,棧的出棧序列數
i64 catalan(int n) {  // 卡特蘭數
    if (n < 0) {
        return 0;
    }
    return C(2 * n, n) * ksm(n + 1, MOD - 2, MOD) % MOD;
}

// 將 n 個不同的元素劃分到 k 個非空集合中的方案數
i64 stirling2(int n, int k) {  // 第二類斯特林數
    if (k > n || k < 0) {
        return 0;
    }
    i64 res = 0;
    for (int i = 0; i <= k; i++) {
        i64 term = C(k, i) * ksm(k - i, n, MOD) % MOD;
        if (i % 2 == 1) {
            term = (MOD - term) % MOD;
        }
        res = (res + term) % MOD;
    }
    return res * invfac[k] % MOD;
}

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

    init(N);
    int n;
    std::cin >> n;

    std::cout << catalan(n);
}

J-解題思路

nm只有16,dfs爆搜即可

J-程式碼實現

#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, m;
    std::cin >> n >> m;

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

    int ans = 0;
    std::vector<int> f(m);
    auto dfs = [&](auto &&self, int x, int cnt) -> void {
        if (x == n) {
            for (int i = 0; i < m; i++) {
                if (f[i] < 0) {
                    return;
                }
            }
            ans = std::max(ans, cnt);
            return;
        }
        self(self, x + 1, cnt);
        for (int i = 0; i < m; i++) {
            f[i] += a[x][i];
        }
        self(self, x + 1, cnt + 1);
        for (int i = 0; i < m; i++) {
            f[i] -= a[x][i];
        }
    };

    dfs(dfs, 0, 0);

    std::cout << ans;
}

相關文章