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;
}
posted @ 2025-07-26 21:58  maburb  阅读(261)  评论(0)    收藏  举报