2025年睿抗机器人开发者大赛CAIP-编程技能赛-高职组(国赛)解题报告 | 珂学家

前言


题解

2025年睿抗机器人开发者大赛CAIP-编程技能赛-高职组(国赛)

感觉这场比赛出题比较典,题意相对清晰(没有阅读理解攻击),整体比较友好。

RC-v1 泼天的富贵

分值: 20分

思路: 分组循环 + 固定长度的滑窗

分组循环保证,至少 k 个元素满足严格递增

然后滑窗,更新最大的结果。

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int n, d, k;
    cin >> n >> d >> k;

    int ans = 0;
    vector<int> cans;
    
    for (int i = 0; i < n; i++) {
        vector<int> arr(d);
        for (int j = 0; j < d; j++) {
            cin >> arr[j];
        }
        int tmp_ans = 0;
        int s = 0;
        while (s + k <= d) {
            int e = s + 1;
            while (e < d && arr[e - 1] < arr[e]) {
                e++;
            }
            
            if (e - s >= k) {
                // e - k, e
                int tmp = 0;
                for (int a = s + 1; a < e; a++) {
                    tmp += arr[a] - arr[a - 1];
                    if (a - s >= k) {
                        tmp -= arr[a - k + 1] - arr[a - k];
                    }
                    tmp_ans = max(tmp_ans, tmp);
                }
            }
            s = e;
        }

        if (ans < tmp_ans) {
            ans = tmp_ans;
            cans = {i + 1};
        } else if (ans == tmp_ans) {
            cans.push_back(i + 1);
        }
    }

    cout << ans << "/" << k << "\n";
    for (int i = 0; i < cans.size(); i++) {
        cout << cans[i] << " \n"[i == cans.size() - 1];
    }

    return 0;
}

RC-v2 行李运输

分值: 25分

思路:二分 + 贪心 check

这题有明显的二阶段性,可以二分承重量,然后贪心构造,最要验证需要的行李数是否小于 k;

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, k;
    cin >> n >> k;

    vector<int> arr(n);
    for (int &x: arr) {
        cin >> x;
    }

    function<bool(int)> check = [arr, n, k](int m) {
        int cnt = 0;
        int s = 0;
        while (s < n) {
            int x = s;
            int tmp = 0;
            while (s < n && tmp + arr[s] <= m) {
                tmp += arr[s];
                s++;
            }
            
            cnt++;
            if (x == s) {
                return false;
            }
        }
        return cnt <= k;
    };
    
    int l = 1, r = 1 << 30;
    while (l <= r) {
        int m = l + (r - l) / 2;
        if (check(m)) {
            r = m - 1;
        } else {
            l = m + 1;
        }
    }

    cout << l << "\n";
    
    return 0;
}

RC-v3 自然倍树

分值:25 分

思路:分治构造

这题的主框架,就是从后序遍历+中序遍历,反解构造出二叉树。

然后验证该二叉树,是否满足自然倍数特性。

而这两个步骤,其实可以合并,这样就省略了树结构的维护。

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

// 分治
bool dfs(vector<int> &arr, int s1, int e1, 
         vector<int> &brr, int s2, int e2, int d) {

    if (s1 > e1) {
        return true;
    }
    // 验证
    if (arr[e1] % d != 0) {
        return false;
    }

    // 获得中序遍历的根
    int pos = -1;
    for (int i = s2; i <= e2; i++) {
        if (brr[i] == arr[e1]) {
            pos = i;
            break;
        }
    }
    int x = pos - s2;
    if (!dfs(arr, s1, s1 + x - 1, brr, s2, pos - 1, d + 1)) {
        return false;
    }
    if (!dfs(arr, s1 + x, e1 - 1, brr, pos + 1, e2, d + 1)) {
        return false;
    }
    return true;
}

int main() {

    int t;
    cin >> t;
    while (t-- > 0) {
        int n;
        cin >> n;
        vector<int> arr(n), brr(n);
        for (int &x: arr) cin >> x;
        for (int &x: brr) cin >> x;

        if (dfs(arr, 0, n - 1, brr, 0, n - 1, 1)) {
            cout << 1 << "\n";
        } else {
            cout << 0 << "\n";
        }
            
    }
    
    return 0;
}

RC-v4 留下买路财

分值:30分

思路:带状态的dijkstra

这里的边权有点特殊,当属于"霸主"的时候,可以理解为负边权。

那是否会形成负圈呢?不会,题目明确一条边只能使用一次。

可以根据这个负边最多使用一次,引入带状态的dijkstra来求解。

定义 dp[s][n],s∈(0,1){dp[s][n], s\in{(0, 1)}}dp[s][n],s∈(0,1), 0表示没使用过负边,1 表示使用过负边。

cpp 复制代码
#include <bits/stdc++.h> 

using namespace std;

struct E {
    int u, w, s;
    E(int u, int w, int s)
        : u(u), w(w), s(s) {}
    bool operator<(const E&rhs) const {
        return w > rhs.w;
    }
};

int main() {

    int n, m, k;
    cin >> n >> m >> k;

    vector<vector<array<int, 2>>> g(n);
    for (int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        u--; v--;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }

    int inf = 0x3f3f3f3f;
    for (int i = 0; i < k; i++) {
        int u, v, a, b;
        cin >> u >> v >> a >> b;
        u--; v--; a--; b--;

        // 带状态的 dijkstra
        vector<int> dp[2];
        dp[0].resize(n, inf);
        dp[1].resize(n, inf);

        priority_queue<E> pq;
        dp[0][a] = 0;
        pq.push(E(a, 0, 0));

        while (!pq.empty()) {
            E e = pq.top(); pq.pop();
            if (e.w > dp[e.s][e.u]) continue;

            for (auto r: g[e.u]) {
                int nv = r[0], w = r[1];

                // 判断是否为负边
                bool f = (e.u == u && nv == v) || (e.u == v &&  nv == u);
                
                if (e.s == 0) {
                    if (f) {
                        if (dp[1][nv] > e.w - w) {
                            dp[1][nv] = e.w - w;
                            pq.push(E(nv, dp[1][nv], 1));
                        }
                    } else {
                        if (dp[0][nv] > e.w + w) {
                            dp[0][nv] = e.w + w;
                            pq.push(E(nv, dp[0][nv], 0));
                        }
                    }
                } else {
                    if (dp[1][nv] > e.w + w) {
                        dp[1][nv] = e.w + w;
                        pq.push(E(nv, dp[1][nv], 1));
                    }
                }
            }
        }
        int z = min(dp[1][b], dp[0][b]);
        if (z < 0) {
            cout << 0 << "\n";
        } else if (z == inf) {
            cout << "@_@\n";
        } else {
            cout << z << "\n";
        }
    }

    return 0;
}

写在最后

相关推荐
我爱娃哈哈16 小时前
SpringBoot + Aviator + 规则中心:轻量级表达式引擎实现营销优惠动态计算
java·spring boot·后端
廋到被风吹走16 小时前
【Spring】IoC容器深度解析:Bean生命周期与循环依赖三级缓存
java·spring·缓存
do better myself16 小时前
php 使用IP2Location限制指定的国家访问实现
开发语言·php
猫头虎16 小时前
Claude Code 永动机:ralph-loop 无限循环迭代插件详解(安装 / 原理 / 最佳实践 / 避坑)
ide·人工智能·langchain·开源·编辑器·aigc·编程技术
a努力。16 小时前
虾皮Java面试被问:JVM Native Memory Tracking追踪堆外内存泄漏
java·开发语言·jvm·后端·python·面试
这周也會开心16 小时前
JVM-垃圾回收器
jvm·算法
橘颂TA16 小时前
【剑斩OFFER】算法的暴力美学——力扣 844 题:比较含退格的字符串
数据结构·c++·算法·力扣·结构与算法
Kratzdisteln16 小时前
【Python】Flask
开发语言·python·flask