VP Educational Codeforces Round 3
A. USB Flash Drives
题意:给你一个
排序后从大到小枚举即可。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n);`
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end(), std::greater<int>());
int sum = 0;
for (int i = 0; i < n; ++ i) {
sum += a[i];
if (sum >= m) {
std::cout << i + 1 << "\n";
return;
}
}
}
B. The Best Gift
题意:总共有
直接统计每一类有多少本书,然后按顺序枚举,每种类型的书都可以和前面所有类型的书一对。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> cnt(11);
for (int i = 0; i < n; ++ i) {
int x;
std::cin >> x;
++ cnt[x];
}
int ans = 0, sum = 0;
for (int i = 1; i <= m; ++ i) {
ans += cnt[i] * sum;
sum += cnt[i];
}
std::cout << ans << "\n";
}
C. Load Balancing
题意:给你
要极差最小,那么最终序列是固定的,我们只需要排序后让大的变成大的,小的变成小的就行,记录需要变的次数。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end(), std::greater<int>());
int ans = 0, sum = std::accumulate(a.begin(), a.end(), 0);
for (int i = 0; i < n; ++ i) {
int x = sum / n;
if (i < sum % n) {
++ x;
}
ans += std::abs(a[i] - x);
}
std::cout << ans / 2 << "\n";
}
D. Gadgets for dollars and pounds
题意:有
你有
考虑二分,如果我们要在第
点击查看代码
void solve() {
int n, m, k, s;
std::cin >> n >> m >> k >> s;
std::vector<i64> 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::vector<std::pair<i64, int>> ta, tb;
for (int i = 0; i < m; ++ i) {
int t, x;
std::cin >> t >> x;
if (t == 1) {
ta.push_back({x, i});
} else {
tb.push_back({x, i});
}
}
std::sort(ta.begin(), ta.end());
std::sort(tb.begin(), tb.end());
int lena = ta.size(), lenb = tb.size();
std::vector<i64> suma(lena + 1), sumb(lenb + 1);
for (int i = 0; i < lena; ++ i) {
suma[i + 1] = suma[i] + ta[i].first;
}
for (int i = 0; i < lenb; ++ i) {
sumb[i + 1] = sumb[i] + tb[i].first;
}
const i64 inf = 1e18;
std::vector<i64> mina(n + 1, inf), minb(n + 1, inf);
for (int i = 0; i < n; ++ i) {
mina[i + 1] = std::min(mina[i], a[i]);
minb[i + 1] = std::min(minb[i], b[i]);
}
auto check = [&](int d) -> std::pair<i64, int> {
i64 va = mina[d], vb = minb[d];
i64 res = inf, p = 0;
for (int i = std::max(0, k - lenb), j = lenb; i <= std::min(k, lena); ++ i) {
while (j > 0 && i + j > k) {
-- j;
}
if (i + j < k) {
break;
}
if (res > suma[i] * va + sumb[j] * vb) {
res = suma[i] * va + sumb[j] * vb;
p = i;
}
}
return {res, p};
};
int l = 1, r = n;
while (l < r) {
int mid = l + r >> 1;
if (check(mid).first <= s) {
r = mid;
} else {
l = mid + 1;
}
}
auto [val, p] = check(l);
if (val > s) {
std::cout << -1 << "\n";
return;
}
int da = 0, db = 0;
for (int i = 0; i < l; ++ i) {
if (a[i] == mina[l]) {
da = i;
break;
}
}
for (int i = 0; i < l; ++ i) {
if (b[i] == minb[l]) {
db = i;
break;
}
}
std::vector<std::pair<int, int>> ans;
for (int i = 0; i < p; ++ i) {
ans.push_back({ta[i].second, da});
}
for (int i = 0; i < k - p; ++ i) {
ans.push_back({tb[i].second, db});
}
std::cout << l << "\n";
for (auto & [x, y] : ans) {
std::cout << x + 1 << " " << y + 1 << "\n";
}
}
E. Minimum spanning tree for each edge
题意:给你一个图,包含某条边的生成树的最小权值。
经典题,考虑建最小生成树,然后根据
点击查看代码
struct DSU {
std::vector<int> fa, cnt;
DSU(int _n) {
init(_n);
}
void init(int _n) {
fa.assign(_n, 0);
cnt.assign(_n, 1);
std::iota(fa.begin(), fa.end(), 0);
}
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
bool merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) {
return false;
}
fa[y] = x;
cnt[x] += cnt[y];
return true;
}
bool same(int x, int y) {
return find(x) == find(y);
}
int size(int x) {
return cnt[find(x)];
}
};
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<std::array<int, 4>> edges(m);
for (int i = 0; i < m; ++ i) {
int u, v, w;
std::cin >> u >> v >> w;
edges[i] = {w, u, v, i};
}
std::sort(edges.begin(), edges.end());
DSU dsu(n + 1);
std::vector<std::vector<std::pair<int, int>>> adj(n + 1);
i64 sum = 0;
for (int i = 0; i < m; ++ i) {
auto & [w, u, v, id] = edges[i];
if (dsu.same(u, v)) {
continue;
}
sum += w;
dsu.merge(u, v);
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
int lg = std::__lg(n) + 1;
std::vector f(n + 1, std::vector<int>(lg + 1));
std::vector max(n + 1, std::vector<int>(lg + 1, 0));
std::vector<int> d(n + 1);
d[1] = 1;
std::queue<int> q;
q.push(1);
while (q.size()) {
int u = q.front(); q.pop();
for (auto & [v, w] : adj[u]) {
if (d[v] == 0) {
d[v] = d[u] + 1;
f[v][0] = u;
max[v][0] = w;
for (int i = 1; i <= lg; ++ i) {
f[v][i] = f[f[v][i - 1]][i - 1];
max[v][i] = std::max(max[v][i - 1], max[f[v][i - 1]][i - 1]);
}
q.push(v);
}
}
}
auto lca = [&](int x, int y) -> int {
if (d[x] < d[y]) {
std::swap(x, y);
}
int res = 0;
for (int i = lg; i >= 0; -- i) {
if (d[f[x][i]] >= d[y]) {
res = std::max(res, max[x][i]);
x = f[x][i];
}
}
if (x == y) {
return res;
}
for (int i = lg; i >= 0; -- i) {
if (f[x][i] != f[y][i]) {
res = std::max({res, max[x][i], max[y][i]});
x = f[x][i], y = f[y][i];
}
}
res = std::max({res, max[x][0], max[y][0]});
return res;
};
std::vector<i64> ans(m);
for (auto & [w, u, v, id] : edges) {
ans[id] = sum - lca(u, v) + w;
}
for (int i = 0; i < m; ++ i) {
std::cout << ans[i] << "\n";
}
}
F. Frogs and mosquitoes
待补
分类:
codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具