2026国信杯具身智能创新大赛-编程技能赛--本科组国赛解题报告 | 珂学家

前言


题解

2026国信杯具身智能创新大赛-编程技能赛的前身是睿抗 CAIP 编程赛。

今年比较特殊,直接略过了省赛,一场定国奖。

总计6题,满分130分,整体难度偏低,唯一的亮点是T4,一道有趣的构造题(最大二分匹配)。


GX-1 十万行代码

分值:10分

题型&知识点:签到

出题背景,挺有意思的

题意:

输出n遍 print('Hello World')

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

using namespace std;

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cout << "print('Hello World')\n";
    }
    return 0;
}

GX-2 一键"三连",这次一定

分值:15分

题型&知识点:模拟

题意:

b站视频的一键三连,给予用户id和动作(Like、Coin 或 Favorite)序列,然后按时间顺序输出完成一键三连的用户id列表。

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

using namespace std;

int main() {

    int n, m;
    cin >> n >> m;
    vector<int> arr(n+1);
  
    auto f = [](string &op) {
        if (op == "Like") return 0;
        else if (op == "Coin") return 1;
        else return 2;
    };

    int left = n;
    vector<int> res;
    for (int i = 0; i < m; i++) {
        int u; string op;
        cin >> u >> op;
        int fv = 1 << f(op);
        if (arr[u] != 7) {
            arr[u] |= fv;
            if (arr[u] == 7) {
                res.push_back(u);
                left--;
            }
        }
    }

    cout << "Complete: ";
    if (res.empty()) cout << "None\n";
    else {
        int z = res.size();
        for (int i = 0; i < z; i++) {
            cout << res[i] << " \n"[i == z - 1];
        }
    }
    cout<< "Incomplete: " << left << "\n";

    return 0;
}

GX-3 宿舍灯光秀

分值:20分

题型&知识点:模拟

题目:

给予一个n*m的二维0-1矩阵,支持按行,按列,按子矩阵翻转操作,求最终的1的个数。

因为数据范围和操作,O(nmq),0≤n,m≤100,q≤1000{O(nmq), 0\le n, m \le 100, q \le 1000}O(nmq),0≤n,m≤100,q≤1000, 即O(107){O(10^7)}O(107), 直接暴力枚举即可。

思考题:如果数据范围和操作数放大,可以如何求解?

如果只求最后的结果,可以用二维差分来加速,如果每个阶段都需要,感觉需要二维带lazy的线段树。

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

using namespace std;

int main() {

    int n, m, q;
    cin >> n >> m >> q;

    int now = 0;
    vector<vector<int>> g(n, vector<int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> g[i][j];
            if (g[i][j] == 1) now++;
        }
    }
    while (q-- > 0) {
        int op;
        cin >> op;
        if (op == 1) {
            int r; cin >> r;
            r--;
            for (int j = 0; j < m; j++) {
                g[r][j] = 1 - g[r][j];
                now += g[r][j] * 2 - 1;
            }
        } else if (op == 2) {
            int c; cin >> c;
            c--;
            for (int i = 0; i < n; i++) {
                g[i][c] = 1 - g[i][c];
                now += g[i][c] * 2 - 1;
            }
        } else {
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            x1--; y1--; x2--; y2--;

            for (int i = x1; i <= x2; i++) {
                for (int j = y1; j <= y2;j++) {
                    g[i][j] = 1 - g[i][j];
                    now += 2 * g[i][j] - 1;
                }
            }
        }
        cout << now << "\n";
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << g[i][j] << " \n"[j == m - 1];
        }
    }

    return 0;
}

GX-4 美丽平方数

分值:25分

题型&知识点:最大二分匹配,构造

题意:

给予2个1~n的排列{aaa}, {bbb}, 需要构造一个排列,使得对于任意的i, 1≤i≤n1\le i \le n1≤i≤n, 满足ai+bi是平方数{a_i + b_i是平方数}ai+bi是平方数

思路:

抽象为一个二分图,分别为{aaa}, {bbb}, 如果满足 ai+bj{a_i+b_j}ai+bj 为平方数,则在aia_iai和bjb_jbj建边,因为要一一匹配,所以就是一道很巧妙且裸的最大二分匹配板子题。

采用匈牙利算法,寻找增广路径,时间复杂度为O(V∗E)O(V*E)O(V∗E).

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

using namespace std;

int main() {

    int N = 100;
    set<int> st;
    for (int i = 1; i <= N; i++) {
        st.insert(i * i);
    }

    int t;
    cin >> t;
    while (t-- > 0) {
        int n;
        cin >> n;

        vector<vector<int>> g(n + 1);

        // 构建二分图
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (st.find(i + j) != st.end()) {
                    g[i].push_back(j);
                }
            }
        }

        // 
        vector<int> match(n + 1, -1);
        function<bool(int u, vector<int>& seen)> dfs;
        dfs = [&](int u, vector<int> &seen) -> bool {
            for (int v: g[u]) {
                if (seen[v]) continue;
                seen[v] = 1;
                if (match[v] == -1 || dfs(match[v], seen)) {
                    match[v] = u;
                    return true;
                }
            }
            return false;
        };

        int cnt = 0;
        for (int i = 1; i <= n; i++) {
            vector<int> seen(n + 1);
            if (dfs(i, seen)) {
                cnt++;
            }
        }

        if (cnt < n) {
            cout << "no\n";
        } else {
            for (int i = 1; i <= n; i++) {
                cout << match[i] << " \n"[i == n];
            }
        }
    }

    return 0;
}

GX-5 不稳定因素

分值:30分

题型和知识点:并查集

关系的传递性,往往采用并查集,来维护集合关系。

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

using namespace std;

struct Dsu {
    int n, m;
    vector<int> arr;

    Dsu(int n)
            : n(n), m(n), arr(n, -1) {}
    int find(int u) {
        if (arr[u] == -1) return u;
        return arr[u] = find(arr[u]);
    }

    void merge(int u, int v) {
        int a= find(u), b = find(v);
        if (a != b) {
            arr[a] = b;
            m--;
        }
    }

    int gs() { return m; }
};

int main() {

    int n, m;
    cin >> n >> m;
    vector<int> ps(n);
    for (int &x: ps) cin >> x;

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

    vector<int64_t> grp(n);
    for (int i = 0; i < n; i++) {
        for (auto &e: g[i]) {
            int p = dsu.find(i), r = e[1];
            grp[p] += r / (1 + abs(ps[i] - ps[e[0]]));
        }
    }

    int sum = 0;
    cout << dsu.gs() << "\n";
    vector<int> res1;
    for (int i = 0; i < n; i++) {
        if (dsu.find(i) == i) {
            res1.push_back(grp[i] / 2);
            sum += grp[i] / 2;
        }
    }
    sort(res1.begin(), res1.end());
    int rn1 = res1.size();
    for (int i = 0; i < rn1; i++) {
        cout << res1[i] << " \n"[i == rn1 - 1];
    }

    int ans = 0;
    vector<int> clist;

    for (int i = 0; i < n; i++) {
        int delta = 0;
        for (auto &e: g[i]) {
            int v1 = e[1] / (1 + abs(ps[i] - ps[e[0]]));
            int v2 = e[1] / (1 + abs(ps[e[0]]));

            delta += v2 - v1;
        }

        if (delta > ans) {
            ans = delta;
            clist = {i};
        } else if (delta == ans) {
            clist.push_back(i);
        }
    }

    if (clist.empty()) cout << "NONE\n";
    else {
        int rn2 = clist.size();
        for (int i = 0; i < rn2; i++) {
            cout << (clist[i] + 1) << " \n"[i == rn2 - 1];
        }
    }

    cout << max(sum, sum + ans) << "\n";

    return 0;
}

GX-6 赶上末班车

分值:30分

题型&知识点:dijkstra最短路

注意单向边,边权的动态计算,非常的板。

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

using namespace std;

struct E {
    int v, s, p, d, t;
    E() {}
    E(int v, int s, int p, int d, int t)
        : v(v), s(s), p(p), d(d), t(t) {}
};

struct X {
    int u;
    int w;
    X() {}
    X(int u, int w)
        : u(u), w(w) {}
};

int main() {

    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    
    int n, m, S, T, ts;
    cin >> n >> m >> S >> T >> ts;

    S--; T--;
    vector<vector<E>> g(n);
    for (int i = 0; i < m; i++) {
        int u, v, s, p, d, t;
        cin >> u >> v >> s >> p >> d >> t;
        u--; v--;
        g[u].push_back(E(v, s, p, d, t));
    }

    auto comp = [](const X&a, const X&b) {
        return a.w > b.w;
    };
    priority_queue<X, vector<X>, decltype(comp)> pq(comp);

    int inf = (int)2e9;
    vector<int> dp(n, inf);

    dp[S] = ts;
    pq.push(X(S, ts));

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

        for (auto &e: g[x.u]) {
            int y = (max(x.w, e.s) - e.s + e.p - 1)  / e.p;
            if (e.s + y * e.p <= e.d) {
                if (dp[e.v] > e.s + y * e.p + e.t) {
                    dp[e.v] = e.s + y * e.p + e.t;
                    pq.push(X(e.v, dp[e.v]));
                }
            }
        }
    }

    if (dp[T] == inf) {
        cout << "Go Taxi\n";
    } else {
        cout << dp[T] << "\n";
    }

    return 0;
}

写在最后

相关推荐
Niuguangshuo7 小时前
论文解读:CTC,端到端序列识别的开山之作
算法·语音识别
讳疾忌医丶7 小时前
深度拆解 RocksDB 内核:基于 C++17 的 FIFO 调度状态机与温度阶梯自愈设计
java·c++·算法·架构
高亦真7 小时前
今天是学习嵌入式的第37天
linux·学习·算法
罗西的思考9 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 --- (2)--- 训练
人工智能·算法·机器学习
深圳市方中禾科技10 小时前
FZH1625 LCD 驱动芯片深度评测与实战指南
算法·led
我不会起名字32211 小时前
一天一道算法题(34):回溯法的经典例题(子集)
java·数据结构·python·算法·golang·深度优先·力扣
huang57914713 小时前
哈希算法的抗碰撞机制与安全性增强策略4
算法
林浩杨_13 小时前
SIGIR 2026|南京大学:Video-GAR:“通过生成 Query 来验证视频语义理解”的生成增强范式
论文阅读·人工智能·算法
Elsa️74614 小时前
算法一周刷题总结
c++·算法
小小程序猴114 小时前
深圳乘路资讯AI培训怎么样?课程靠谱吗?——一套课程可信度评估模型与实证分析
人工智能·算法