ZZJC新生训练赛第十九场题解

链接:https://ac.nowcoder.com/acm/contest/98176
密码:svdf465mik8

难度分类

  • 由题目分值决定

A-解题思路

按照题意模拟即可,注意0分的时候不需要再扣分

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

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

    int ans = 0;
    for (auto ch : s) {
        if (ch == 'N' && ans > 0) {
            ans--;
        }
        ans += ch == 'Y';
    }

    std::cout << ans;
}

B-解题思路

题目说是前缀,但不是所有前缀,因此前面某部分是负数,但是后面是正数依然可以算作答案,因此找到最右边的一个整数前缀和即可

B-代码实现

#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<i64> pre(n + 1);
    for (int i = 0; i < n; i++) {
        int x;
        std::cin >> x;

        pre[i + 1] = pre[i] + x;
    }

    for (int i = n; i >= 0; i--) {
        if (pre[i] >= 0) {
            std::cout << i;
            break;
        }
    }
}

C-解题思路

对这个数列的每个数都判断一下是不是质数就行

C-代码实现

#include <bits/stdc++.h>

using i64 = long long;

bool prime(int x) {
    if (x < 2) {
        return 0;
    }
    for (int i = 2; i <= sqrt(x); i++) {
        if (x % i == 0) {
            return 0;
        }
    }
    return 1;
}

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

    int n, a, d, ans = 0;
    std::cin >> n >> a >> d;

    for (int i = 0; i < n; i++) {
        ans += prime(a + i * d);
    }

    std::cout << ans;
}

D-解题思路

根据题目要求的写一个排序条件即可

D-代码实现

#include <bits/stdc++.h>

using i64 = long long;

bool cmp(std::array<int, 2> x, std::array<int, 2> y) {
    if (x[0] != y[0]) {
        return x[0] > y[0];
    }
    return x[1] < y[1];
}

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

    int n;
    std::cin >> n;

    std::vector<std::array<int, 2>> a;
    for (int i = 1; i <= n; i++) {
        int x;
        std::cin >> x;

        a.push_back({x, i});
    }

    std::sort(a.begin(), a.end(), cmp);

    for (auto [x, y] : a) {
        std::cout << y << "\n";
    }
}

E-解题思路

互质就是两个数字gcd是1,显然插入1就行,所以看数字之间有哪些非1gcd即可

E-代码实现

#include <bits/stdc++.h>

using i64 = long long;

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

    int n;
    std::cin >> n;

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

    int ans = 0;

    for (int i = 1; i < n; i++) {
        ans += (std::__gcd(a[i], a[i - 1]) > 1);
    }

    std::cout << ans;
}

F-解题思路

现根据结束时间升序再根据开始时间升序贪心的选择即可

F-代码实现

#include <bits/stdc++.h>

using i64 = long long;

bool cmp(std::pair<int, int> a, std::pair<int, int> b) {
    if (a.second != b.second) {
        return a.second < b.second;
    }
    return a.first < b.first;
}

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

    int n;
    std::cin >> n;

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

    std::sort(a.begin(), a.end(), cmp);

    int f = 0, cnt = 0;
    for (int i = 0; i < n; i++) {
        if (a[i].first >= f) {
            f = a[i].second;
            cnt++;
        }
    }

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

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

    i64 n, m = 0, ans = 0;
    std::cin >> n;

    for (int i = 1; i <= n; i++) {
        int d = n / i - (n / (i + 1));
        ans += i * d;

        if (d == 1) {
            m = n / (i + 1);
            break;
        }
    }

    for (int i = 1; i <= m; i++) {
        ans += n / i;
    }

    std::cout << ans;
}

H-解题思路

考虑每个位置选和不选,n只有22,dfs暴力搜索即可

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, ans = 0;
    std::cin >> n;

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

    auto dfs = [&](auto &&self, int pos, int sum) -> void {
        if (pos == n) {
            ans += sum == 0;
            return;
        }
        self(self, pos + 1, sum);
        self(self, pos + 1, sum + a[pos]);
    };

    dfs(dfs, 0, 0);

    std::cout << ans;
}

I-解题思路

要最大化最后的和,显然取最大的m个数作为连续段的最大值是最优的,然后再看他们之间的下标差了多少,这样就能知道中间可以有多少个数字可以选择,本题数据较大,需要开longlong

I-代码实现

#include <bits/stdc++.h>

using i64 = long long;

const int MOD = 1e9 + 7;

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::array<int, 2>> p;
    for (int i = 0; i < n; i++) {
        int x;
        std::cin >> x;
        p.push_back({x, i});
    }

    auto cmp1 = [&](std::array<int, 2> a, std::array<int, 2> b) -> bool { return a[0] > b[0]; };
    auto cmp2 = [&](std::array<int, 2> a, std::array<int, 2> b) -> bool { return a[1] < b[1]; };

    std::sort(p.begin(), p.end(), cmp1);
    std::sort(p.begin(), p.begin() + m, cmp2);

    i64 sum = 0, cnt = 1;
    for (int i = 0; i < m - 1; i++) {
        cnt = (cnt * (p[i + 1][1] - p[i][1])) % MOD;
        sum += p[i][0];
    }
    sum += p[m - 1][0];

    std::cout << sum << "\n";
    std::cout << cnt << "\n";
}

J-解题思路

nm只有200,暴力的搜索每一个'.'的位置并对它对相邻的'.'都进行填充,看能填充多少次

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>> vis(n + 1, std::vector<int>(m + 1));
    std::vector<std::vector<char>> g(n + 1, std::vector<char>(m + 1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            std::cin >> g[i][j];
            if (g[i][j] == '#') {
                vis[i][j] = 1;
            }
        }
    }

    auto isin = [&](int x, int y) { return 1 <= x && x <= n && 1 <= y && y <= m; };

    auto dfs = [&](auto &&self, int x, int y) {
        if (vis[x][y]) {
            return;
        }

        vis[x][y] = 1;
        g[x][y] = '#';

        if (isin(x, y + 1) && !vis[x][y + 1]) {
            self(self, x, y + 1);
        }
        if (isin(x, y - 1) && !vis[x][y - 1]) {
            self(self, x, y - 1);
        }
        if (isin(x + 1, y) && !vis[x + 1][y]) {
            self(self, x + 1, y);
        }
        if (isin(x - 1, y) && !vis[x - 1][y]) {
            self(self, x - 1, y);
        }
    };

    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (g[i][j] == '.') {
                ans++;
                g[i][j] = '#';
                dfs(dfs, i, j);
            }
        }
    }

    std::cout << ans;
}
posted @ 2024-12-02 21:08  udiandianis  阅读(41)  评论(0)    收藏  举报