AcWing 第2场周赛
竞赛 - AcWing
3626 三元一次方程
AcWing 3626. 三元一次方程 - AcWing
两层循环
#include <iostream> using namespace std; void find(int n) { for (int x = 0; x <= 1000 / 3; x++) { for (int y = 0; y <= 1000 / 5; y++) { int res = n - 3 * x - 5 * y; if (res < 0) { continue; } else if (res % 7 == 0) { cout << x << " " << y << " " << res / 7 << endl; return; } } } cout << "-1" << endl; } int main() { int m; cin >> m; while (m--) { int n; cin >> n; if (n < 0) { cout << "-1" << endl; continue; } find(n); } }
3627⭐最大差值
3627. 最大差值 - AcWing题库
考查贪心,所有输入的不是0的数排序,每次操作取最大的数++,由于每个数最大可以是1e9,int可能溢出,需要用 long long
#include <algorithm> #include <iostream> using namespace std; const int N = 2e5 + 10; int t, n, k; int a[N]; int main() { cin >> t; while (t--) { cin >> n >> k; int idx = 0; for (int i = 0; i < n; i++) { int x; scanf("%d", &x); if (x != 0) a[idx++] = x; } sort(a, a + idx); long long res = a[--idx]; int i = idx - 1; while (k--) if (i >= 0) res += a[i--]; cout << res << endl; } }
3628⭐⭐边的删减
3628. 边的删减 - AcWing题库
刚开始有点傻,打算用克鲁斯卡尔生成最小生成树,题意明显不是这样的
最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径 最短路径是从一点出发,到达目的地的路径最小。所以本题的解题思路先用堆优化版迪杰斯特拉求各点到根节点的最短路径,然后用DFS从根节点找k条边的连通图(任意一个包含k条边的连通块就是答案)
因为 w <= 1e9,所以dist数组长度要用 long long 存
考查堆优化Dijkstra、DFS
#include <algorithm> #include <cstring> #include <iostream> #include <queue> #include <vector> #define x first #define y second using namespace std; typedef long long LL; typedef pair<LL, int> PII; const int N = 10e5 + 10, M = 2 * N; int n, m, k; int h[N], e[M], ne[M], idx, w[M], id[M]; LL dist[N]; bool st[N]; void add(int a, int b, int c, int d) { e[idx] = b; w[idx] = c; id[idx] = d; ne[idx] = h[a]; h[a] = idx++; } void dijkstra() { priority_queue<PII, vector<PII>, greater<PII>> heap; // 定义为小根堆 memset(dist, 0x3f, sizeof dist); dist[1] = 0; heap.push({0, 1}); while (heap.size()) { auto u = heap.top(); heap.pop(); if (st[u.y]) continue; st[u.y] = true; for (int i = h[u.y]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > u.x + w[i]) { heap.push({u.x + w[i], j}); dist[j] = u.x + w[i]; } } } } vector<int> ans; void dfs(int x) { st[x] = true; for (int i = h[x]; ~i; i = ne[i]) { int j = e[i]; if (!st[j] && dist[x] + w[i] == dist[j]) { if (ans.size() < k) ans.push_back(id[i]); dfs(j); } } } int main() { cin >> n >> m >> k; memset(h, -1, sizeof h); for (int i = 1; i <= m; i++) { int a, b, c; cin >> a >> b >> c; add(a, b, c, i); add(b, a, c, i); } dijkstra(); memset(st, 0, sizeof st); dfs(1); cout << ans.size() << endl; for (auto i : ans) cout << i << " "; return 0; }
查看更多关于C++ 算法竞赛、02 周赛篇 | AcWing 第2场周赛的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did254282