AtCoder Beginner Contest 315

A - tcdr (abc315 A)

题目大意

从给定的字符串中删除元音字母。

解题思路

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <bits/stdc++.h>

using i64 = long long;

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

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

std::string ans = {};
for (auto &item : s) {
if (item == 'a' || item == 'e' || item == 'i' || item == 'o' || item == 'u') continue;
ans.push_back(item);
}

std::cout << ans << '\n';

return 0;
}



B - The Middle Day (abc315 B)

题目大意

给定一年有\(n\)个月,每个月有\(d_i\)天,找一年中的中间一天是几月几日。

解题思路

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>

using i64 = long long;

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

int n;
std::cin >> n;

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

i64 mid = (sum + 1) / 2;

int cur = 1;
while (mid > 0) {
if (mid - mouth[cur] <= 0) break;
mid -= mouth[cur ++];
}

std::cout << cur << ' ' << mid << std::endl;

return 0;
}



C - Flavors (abc315 C)

题目大意

\(n\)盘菜,种类和好吃度分别为\(f_i\)\(s_i\),从中选择两盘菜来吃。如果种类相同,则满意度为\(s + \frac{t}{2}\), 否则为\(s + t\)。求出最大满意度。

解题思路

枚举一下可能出现的情况就好。

首先枚举每个种类的菜好吃度最大的两盘的满意度。然后枚举不同种类中好吃度最大的两盘菜。最后输出最大值即可。

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <algorithm>
#include <bits/stdc++.h>
#include <functional>

using i64 = long long;
using PII = std::pair<int, int>;

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

int n;
std::cin >> n;

std::vector<std::vector<int>> a(n + 1, std::vector<int>());
for (int i = 1;i <= n;i ++) {
int x, y;
std::cin >> x >> y;
a[x].emplace_back(y);
}

int ans = 0;
std::vector<int> max(n + 1);
for (int i = 1;i <= n;i ++) {
if (a[i].empty()) continue;
std::nth_element(a[i].begin(), a[i].begin()+1, a[i].end(), std::greater<int>());
if (a[i].size() >= 2) {
ans = std::max(ans, a[i][0] + a[i][1] / 2);
}
max[i] = a[i][0];
}

std::nth_element(max.begin(), max.begin() + 1, max.end(), std::greater<int>());
ans = std::max(ans, max[0] + max[1]);
std::cout << ans << '\n';

return 0;
}



D - Magical Cookies (abc315 D)

题目大意

\(n*m\)的 网格中,每个格子有一块点心,种类为\(c_{ij}\),当一行或一列有两块以上相同种类的点心时,将他们都删去。求最后网格还剩多少块点心。

解题思路

硬模拟。

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <array>
#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<int, int>;

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

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

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

std::vector<std::array<int, 27>> cntr(n + 1), cntc(m + 1);
for (int i = 1;i <= n;i ++) {
for (int j = 1;j <= m;j ++) {
cntr[i][a[i][j] - 'a'] ++;
cntc[j][a[i][j] - 'a'] ++;
}
}

std::vector<bool> visr(n + 1), visc(m + 1);
int hc = n, wc = m;
for(int _ = 1; _ <= n + m; _++) {
std::vector<PII> tx, ty;
for(int i = 1; i <= n; i++) {
if(visr[i]) continue;
for(int j = 0; j < 26; j++) {
if(cntr[i][j] == wc && wc > 1) {
tx.emplace_back(i, j);
}
}
}

for(int i = 1; i <= m; i++) {
if(visc[i]) continue;
for(int j = 0; j < 26; j++) {
if(cntc[i][j] == hc && hc > 1) {
ty.emplace_back(i, j);
}
}
}

for(auto &[x, y] : tx) {
visr[x] = true;
for(int i = 1; i <= m; i++) {
cntc[i][y]--;
}
hc--;
}

for(auto &[x, y] : ty) {
visc[x] = true;
for(int i = 1; i <= n; i++) {
cntr[i][y]--;
}
wc--;
}
}

std::cout << wc * hc << "\n";

return 0;
}



E - Prerequisites (abc315 E)

题目大意

\(n\)本书,每本书需要先读给定的\(c_i\)本书才能读。求读第一本书之前需要读的读书顺序。要求需要读的书籍最小。

解题思路

\(dfs\)去找每本书需要的前置书籍,然后递归回来的顺序就是需要的顺序。好像拓扑排序也能写。

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <algorithm>
#include <array>
#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<int, int>;

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

int n;
std::cin >> n;

std::vector<std::vector<int>> g(n + 1, std::vector<int>());
for (int i = 1;i <= n;i ++) {
int c;
std::cin >> c;
for (int _ = 1;_ <= c;_ ++) {
int x;
std::cin >> x;
g[i].emplace_back(x);
}
}

std::vector<bool> vis(n + 1);
std::function<void(int)> dfs = [&](int u) -> void {
if (vis[u]) return ;
for (int v : g[u]) {
dfs(v);
}
vis[u] = true;
if (u != 1) {
std::cout << u << ' ';
}
};

dfs(1);
std::cout << std::endl;

return 0;
}



F - Shortcuts (abc315 F)

题目大意

balabalabala好难概括。

解题思路

\(dp[i][j]\)为走了前\(i\)个点,已经跳过了\(j\)个点,需要走的最小距离。

最大答案大约是\(1e4*1e4\),这时候跳过\(30\)个点就大于了,所以只需要枚举跳过\(30\)个点以内的情况。

神奇的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>

using i64 = long long;

constexpr int K = 30;
constexpr double inf = 1E9;

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

int N;
std::cin >> N;

std::vector<int> X(N), Y(N);
for (int i = 0; i < N; i++) {
std::cin >> X[i] >> Y[i];
}

std::vector<std::vector<double>> dp(N, std::vector<double>(K, inf));
double ans = inf;
dp[0][0] = 0;
for (int i = 0; i < N - 1; i++) {
for (int j = 0; j < K; j++) {
for (int x = i + 1; x < N && j + x - i - 1 < K; x++) {
int nj = j + x - i - 1;
dp[x][nj] = std::min(dp[x][nj], dp[i][j] + std::sqrt((X[i] - X[x]) * (X[i] - X[x]) + (Y[i] - Y[x]) * (Y[i] - Y[x])));
}
}
}
for (int i = 0; i < K; i++) {
ans = std::min(ans, dp[N - 1][i] + (i == 0 ? 0 : 1 << (i - 1)));
}
std::cout << std::fixed << std::setprecision(10) << ans << "\n";

return 0;
}



G - Ai + Bj + Ck = X (1 <= i, j, k <= N) (abc315 G)

题目大意

<++>

解题思路

<++>

神奇的代码
1



Ex - Typical Convolution Problem (abc315 Ex)

题目大意

<++>

解题思路

<++>

神奇的代码
1




AtCoder Beginner Contest 315
https://acmicpc.top/2023/08/23/AtCoder Beginner Contest 315/
作者
江欣婷
发布于
2023年8月23日
许可协议