AtCoder Beginner Contest 416
A - Vacation Validation
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, l, r;
std::cin >> n >> l >> r;
std::string s;
std::cin >> s;
for (int i = l; i <= r; ++ i) {
if (s[i - 1] != 'o') {
std::cout << "No\n";
return;
}
}
std::cout << "Yes\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
B - 1D Akari
题意:给你一个字符串\(s\),你要构造一个\(t\),使得\(s\)和\(t\)是#号的位置相同。然后'o'最多,且两个'o'之间至少一个'#'。
从左到右遍历,记一个\(flag\)初始为\(1\),遇到非'#'的位置且\(flag=1\)可以填'o',然后\(flag=0\),否则遇到'#'则\(flag=1\)。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
std::string s;
std::cin >> s;
int n = s.size();
bool flag = true;
for (int i = 0; i < n; ++ i) {
if (s[i] != '#') {
if (flag) {
s[i] = 'o';
flag = false;
} else {
s[i] = '.';
}
} else {
flag = true;
}
}
std::cout << s << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
C - Concat (X-th)
爆搜所有组合方式然后排序。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, m, k;
std::cin >> n >> m >> k;
std::vector<std::string> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<std::string> s;
auto dfs = [&](auto & self, int cnt, std::string t) -> void {
if (cnt == m) {
s.push_back(t);
return;
}
for (int i = 0; i < n; ++ i) {
self(self, cnt + 1, t + a[i]);
}
};
dfs(dfs, 0, "");
std::ranges::sort(s);
std::cout << s[k - 1] << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
D - Match, Mod, Minimize 2
题意:给你两个数组\(A, B\),任意排列\(A\),求\(\sum_{i=1}^{n} (A_i + B_i) \% mod\)最小。
两个数原本是\(a+b\),如果\(a+b\geq mod\),取模后可以看作\(a+b-mod\)。那么希望\(a+b\geq mod\)的对数最多。
可以从大到小遍历\(A\),每次找符号条件的最小的\(B_i\)。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n), b(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
for (int i = 0; i < n; ++ i) {
std::cin >> b[i];
}
std::ranges::sort(a, std::greater<>());
std::multiset<int> s;
for (auto & x : b) {
s.insert(x);
}
i64 ans = 0;
for (int i = 0; i < n; ++ i) {
auto it = s.lower_bound(m - a[i]);
if (it == s.end()) {
-- it;
}
ans += (a[i] + *it) % m;
s.erase(it);
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
E - Development
题意:\(n\)个点\(m\)条边,每条边有边权。\(k\)个机场,机场里任何两个点可以花费\(T\)时间互相到达。三种操作,一种是添加一条边,一种是把一个点加入机场,一种是询问所有点对的最短路的和。
两个点的最短路,要么不坐飞机,要么坐飞机,不坐飞机就是最短路,坐就是求出两个点到最近的一个机场的距离,然后总距离是这两个距离加\(T\)。
可以\(floyd\)处理两点最短路,然后以每个机场为源点\(dijkstra\)。
每次添加一条边,就根据这条边两个点\(floyd\)一下,这是经典用法,加入一条边只需要对两个点都跑一次。然后重新跑一遍\(dijkstra\)。对于加入一个机场,用它跑一下\(dijkstra\)。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, m;
std::cin >> n >> m;
constexpr i64 inf = 1e18;
std::vector d(n, std::vector<i64>(n, inf));
for (int i = 0; i < n; ++ i) {
d[i][i] = 0;
}
for (int i = 0; i < m; ++ i) {
int u, v;
i64 w;
std::cin >> u >> v >> w;
-- u, -- v;
d[u][v] = d[v][u] = std::min(d[u][v], w);
}
for (int k = 0; k < n; ++ k) {
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
d[i][j] = std::min(d[i][j], d[i][k] + d[k][j]);
}
}
}
std::vector<i64> d1(n, inf);
using PII = std::pair<i64, int>;
std::priority_queue<PII, std::vector<PII>, std::greater<>> heap;
int K, T;
std::cin >> K >> T;
std::vector<int> a;
for (int i = 0; i < K; ++ i) {
int u;
std::cin >> u;
-- u;
a.push_back(u);
d1[u] = 0;
heap.emplace(0, u);
}
while (heap.size()) {
auto [dist, u] = heap.top(); heap.pop();
if (dist != d1[u]) {
continue;
}
for (int v = 0; v < n; ++ v) {
if (d1[v] > dist + d[u][v]) {
d1[v] = dist + d[u][v];
heap.emplace(d1[v], v);
}
}
}
int Q;
std::cin >> Q;
while (Q -- ) {
int op;
std::cin >> op;
if (op == 1) {
int u, v;
i64 w;
std::cin >> u >> v >> w;
-- u, -- v;
if (d[u][v] > w) {
d[u][v] = d[v][u] = w;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
d[i][j] = std::min(d[i][j], d[i][u] + d[u][j]);
}
}
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
d[i][j] = std::min(d[i][j], d[i][v] + d[v][j]);
}
}
}
for (auto & x : a) {
heap.emplace(0, x);
}
while (heap.size()) {
auto [dist, u] = heap.top(); heap.pop();
if (dist != d1[u]) {
continue;
}
for (int v = 0; v < n; ++ v) {
if (d1[v] > dist + d[u][v]) {
d1[v] = dist + d[u][v];
heap.emplace(d1[v], v);
}
}
}
} else if (op == 2) {
int u;
std::cin >> u;
-- u;
d1[u] = 0;
a.push_back(u);
heap.emplace(0, u);
while (heap.size()) {
auto [dist, u] = heap.top(); heap.pop();
if (dist != d1[u]) {
continue;
}
for (int v = 0; v < n; ++ v) {
if (d1[v] > dist + d[u][v]) {
d1[v] = dist + d[u][v];
heap.emplace(d1[v], v);
}
}
}
} else {
i64 ans = 0;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
i64 dist = std::min(d[i][j], d1[i] + T + d1[j]);
if (dist < inf) {
ans += dist;
}
}
}
std::cout << ans << "\n";
}
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}