AcWing第2周周赛题解

A. AcWing 3626. 三元一次方程

题目链接:https://www.acwing.com/problem/content/3629/

题目大意:求出三元一次方程 3x+5y+7z=n 的一组非负整数解。

解题思路:枚举 xy

示例程序:

#include <bits/stdc++.h>
using namespace std;

int T, n;

void solve() {
    for (int x = 0; 3*x <= n; x++) {
        for (int y = 0; 3*x+5*y <= n; y++) {
            if ((n - 3*x - 5*y) % 7 == 0) {
                int z = (n - 3 * x - 5 * y) / 7;
                cout << x << " " << y << " " << z << endl;
                return;
            }
        }
    }
    cout << -1 << endl;
}

int main() {
    cin >> T;
    while (T--) {
        cin >> n;
        solve();
    }
    return 0;
}

B. AcWing 3627. 最大差值

题目链接:https://www.acwing.com/problem/content/3630/

题目大意:给定一个数列。每次操作选择两个非 0 的元素 ai 和 aj,然后选择一个整数 c(0≤c≤ai),使得 ai 减少 c,aj 增加 c。问,在操作全部完成后,序列中的最大值和最小值之差是多少。

解题思路:贪心。数列中最小的数只能变为 0,每次选择最大的两个数(设为 aiaj)满足 aiaj,然后将 ai 减去 ai(变为 0),将 aj 加上 ai(变为 aj+ai)。具体实现时我准备用优先队列实现。

示例程序:

#include <bits/stdc++.h>
using namespace std;

priority_queue<long long> que;
int T, n, k;
long long a, b;

int main() {
    cin >> T;
    while (T--) {
        while (!que.empty()) que.pop();
        cin >> n >> k;
        while (n--) {
            cin >> a;
            que.push(a);
        }
        while (k--) {
            a = que.top();
            que.pop();
            b = que.top();
            que.pop();
            que.push(a+b);
        }
        cout << que.top() << endl;
    }
    return 0;
}

C. AcWing 3628. 边的删减

题目链接:https://www.acwing.com/problem/content/description/3631/

题目大意:最多保留 k 条边,使剩下的图中与节点 1 的最短距离等于之前的图中的最短距离的点的数量尽可能地大,求保留了哪些边。

解题思路:

  • 先求最短路(我用的spfa)
  • 然后bfs一遍,如果节点 1u 的最短路径长度加上 uv 的长度等于节点 1v 的最短路径长度,则算入这条边,同时 v 入队。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, m, k;
long long dis[maxn];
bool inq[maxn], ok[maxn], vis[maxn];
queue<int> que;
struct Edge { int v, w, id; };
vector<Edge> g[maxn];

void spfa() {
    memset(dis, -1, sizeof(dis));
    dis[1] = 0;
    que.push(1);
    while (!que.empty()) {
        int u = que.front(); que.pop(); inq[u] = false;
        for (auto e : g[u]) {
            int v = e.v, w = e.w;
            if (dis[v] == -1 || dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                if (!inq[v]) {
                    inq[v] = true;
                    que.push(v);
                }
            }
        }
    }
}

void bfs() {
    int cnt = 0; // cnt 表示保留的边的数量
    vis[1] = true;
    while (!que.empty()) que.pop();
    que.push(1);
    while (!que.empty() && k > 0) {
        int u = que.front();
        que.pop();
        for (auto e : g[u]) {
            int v = e.v, w = e.w;
            if (!vis[v] && dis[u] + w == dis[v] && k > 0) {
                vis[v] = true;
                ok[e.id] = true;
                k --;
                cnt++;
                que.push(v);
            }
        }
    }
    cout << cnt << endl;
    for (int i = 1; i <= m; i++)
        if (ok[i])
            cout << i << " ";
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({v, w, i});
        g[v].push_back({u, w, i});
    }
    spfa();
    bfs();
    return 0;
}
posted @   quanjun  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示