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

浙公网安备 33010602011771号