AcWing第8场周赛题解
A. 3770. 最小消耗
题目链接:https://www.acwing.com/problem/content/description/3773/
题目大意:按照题目要求消灭两种类型怪兽(可以消耗 c 转换)的最小消耗。
解题思路:循环记录 0 和 1 出现的次数,消灭一个 0 的最小消耗为 min(a, b+c),消灭一个 1 的最小消耗为 min(a+c, b)。
示例程序:
#include <bits/stdc++.h>
using namespace std;
int T, n, a, b, c, c0, c1;
char s[1010];
int main() {
cin >> T;
while (T--) {
cin >> n >> a >> b >> c >> s;
c0 = c1 = 0;
for (int i = 0; i < n; i++)
(s[i] == '0') ? c0++ : c1++;
cout << c0 * min(a, b+c) + c1 * min(a+c, b) << endl;
}
return 0;
}
B. AcWing 3771. 选取石子
题目链接:https://www.acwing.com/problem/content/3774/
题目大意:从数列里面选出一些数满足 \(a_i - a_j = i - j\)。
解题思路:将所有 \(a_i\) 放入 \(a_i - i\) 的桶中(实际实现时用的 map),找最大的那个桶。
示例程序:
#include <bits/stdc++.h>
using namespace std;
map<int, long long> mp;
int n, a;
long long ans;
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a;
mp[a-i] += a;
}
for (auto p : mp)
ans = max(ans, p.second);
cout << ans << endl;
return 0;
}
C. 3772. 更新线路
题目链接:https://www.acwing.com/problem/content/3775/
题目大意:求一条路径走过来最短路最少和最多更新次数。
解题思路:返图+最短路+最短路计数。最少更新次数是不是最短路径的点,最多更新次数是:不是最短路径的点+最短路径不唯一的点。由于边权为 \(1\),所以可以 bfs 求最短路。注意:强连通图的条件很重要,这能保证反图也强连通。
最主要的逻辑在第 40 ~ 42 行。请认真体会(调了好长时间)
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, m, k, p[maxn], dis[maxn], cnt[maxn], pre[maxn];
vector<int> g[maxn];
queue<int> que;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
while (m--) {
int u, v;
cin >> u >> v;
g[v].push_back(u); // 建反图
}
cin >> k;
for (int i = 1; i <= k; i++) cin >> p[i];
memset(dis, -1, sizeof(int)*(n+1));
dis[p[k]] = 0;
cnt[p[k]] = 1;
que.push(p[k]);
while (!que.empty()) {
int u = que.front();
que.pop();
for (auto v : g[u]) {
if (dis[v] == -1) {
dis[v] = dis[u] + 1;
cnt[v] = 1;
pre[v] = u;
que.push(v);
}
else if (dis[v] == dis[u] + 1)
cnt[v]++;
}
}
int c1 = 0, c2 = 0;
for (int i = 1; i <= k; i++) {
int u = p[i];
if (i < k && cnt[u]==1 && pre[u] == p[i+1]) continue; // 新增条件:非最短路但是不唯一也不更新
if (i < k && dis[u] != dis[p[i+1]] + 1) c1++;
if (cnt[u] > 1 || i < k && pre[u] != p[i+1]) c2++;
}
cout << c1 << " " << c2 << endl;
return 0;
}
浙公网安备 33010602011771号