VP Educational Codeforces Round 38 (Rated for Div. 2)
A. Word Correction
模拟
点击查看代码
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
std::string ans;
auto check = [&](char c) -> bool {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y';
};
for (int i = 0; i < n; ++ i) {
ans += s[i];
int j = i + 1;
while (j < n && check(s[i]) && check(s[j])) {
++ j;
}
i = j - 1;
}
std::cout << ans << "\n";
}
B. Run For Your Prize
题意:两个人在数轴的两段,每秒钟走一步,有\(n\)个物品,求拿走全部物品的最短时间。
每个物品被距离最近的人拿走,所有物品被拿走的时间取最大值。
点击查看代码
void solve() {
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 = 0; i < n; ++ i) {
ans = std::max(ans, std::min(a[i] - 1, 1000000 - a[i]));
}
std::cout << ans << "\n";
}
C. Constructing Tests
题意:一个\(n\times n\)的\(01\)矩阵如果满足任意一个\(m\times m\)的子矩阵都至少有一个\(0\),且\(1\)的数量尽可能多,这个矩阵就满足\((n,m)\)的条件。现在给出\(1\)的数量为\(x\),找\(n, m\)。
题目要求我们反向想,但这并不好想,先正着想一个满足\(n, m\)的矩阵有多少个\(1\)。发现一个每隔\(m\)行\(m\)列放一个\(0\),手画一下发现总共有\((\lfloor \frac{n}{m} \rfloor)^2\)个\(0\),那么总共有\(n^2 - (\lfloor \frac{n}{m} \rfloor)^2\)个\(1\)。那么我们就是求\(n^2 - (\lfloor \frac{n}{m} \rfloor)^2 = x\)。
那么可以得到\((n + \lfloor \frac{n}{m} \rfloor) \times (n - \lfloor \frac{n}{m} \rfloor) = x\)。那么我们可以枚举\(x\)的因子,然后求出\(n\)和\(m\)。
点击查看代码
void solve() {
i64 x;
std::cin >> x;
if (x == 0) {
std::cout << 1 << " " << 1 << "\n";
return;
}
if (x == 1) {
std::cout << -1 << "\n";
return;
}
//n * n - (n / m) * (n / m) = x
//(n + n / m)(n - n / m) = x
for (i64 i = 1; i * i < x; ++ i) {
if (x % i == 0) {
i64 a = x / i, b = i;
i64 n = (a + b) / 2, m = (a + b) / (a - b);
if (n * n - (n / m) * (n / m) == x) {
std::cout << n << " " << m << "\n";
return;
}
}
}
std::cout << -1 << "\n";
}
D. Buy a Ticket
题意:给你一个图,每个点有点权,每个边有边权。对每个点求一个终点,使得这个点到终点的最短路长度的两倍加终点点权的值最小。
超级源点。
一开始把每个点都入队,值为这个点的点权,然后跑最短路。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
using PII = std::pair<i64, i64>;
std::vector<std::vector<PII>> adj(n);
for (int i = 0; i < m; ++ i) {
int u, v;
i64 w;
std::cin >> u >> v >> w;
-- u, -- v;
adj[u].push_back({v, w * 2});
adj[v].push_back({u, w * 2});
}
std::vector<i64> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
const i64 inf = 1e18;
std::priority_queue<PII, std::vector<PII>, std::greater<PII>> heap;
std::vector<i64> dist(n, inf);
for (int i = 0; i < n; ++ i) {
dist[i] = a[i];
heap.emplace(dist[i], i);
}
while (heap.size()) {
auto [d, u] = heap.top(); heap.pop();
if (d != dist[u]) {
continue;
}
for (auto & [v, w] : adj[u]) {
if (dist[v] > d + w) {
dist[v] = d + w;
heap.emplace(dist[v], v);
}
}
}
for (int i = 0; i < n; ++ i) {
std::cout << dist[i] << " \n"[i == n - 1];
}
}