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

news2025/5/22 23:29:09

前言

在这里插入图片描述


题解

2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)。

vp了下,题目挺好的,难度也适中,但是彻底红温了。

第二题,题意不是那么清晰, M i n ( K 1 , K 2 ) Min(K_1, K_2) Min(K1,K2)容易求,但是题目最后要求真的很难get到点(缺乏对case的必要解释)。

第四题,是一道裸的拓扑排序,但是卡内存,关于这个仁者见仁智者见智。

如果再备战 睿抗 CAIP 编程赛,需要学习一些内存优化的技巧。在这里插入图片描述


RC-u1 睿抗,启动!

分值: 15分

思路: 分组循环

这题,有一处地方有点小意外

如果 S 为 yourname,请将 S 改为你的名字的拼音拼写

其实我还是觉得太突兀了,这种莫名SPJ的元素

#include <bits/stdc++.h>

using namespace std;

int tag(char c) {
    if (c >= 'A' && c <= 'Z') return 0;
    else if (c >= 'a' && c <= 'z') return 1;
    return 2;
}

int main() {

    int n;
    cin >> n;
    string s;
    cin >> s;

    if (s == "yourname") s = "zhangsan";

    string ns = s;
    for (int i = 0; i < n; i++) {
        int m = ns.size();
        for (int j = 0; j < m; j++) {
            int x = tag(ns[j]);
            if (x == 0) {
                ns[j] = (char)((ns[j] - 'A' + 1) % 26 + 'A');
            } else if (x == 1) {
                ns[j] = (char)((ns[j] - 'a' + 25) % 26 + 'a');
            }
        }
        int k = 0;
        while (k < m) {
            int x = tag(ns[k]);
            int k2 = k + 1;
            while (k2 < m && tag(ns[k2]) == x) {
                k2 ++;
            }

            if (k2 - k >= 3) {
                for (int j = k; j < k2; j++) {
                    if (x == 0) {
                        ns[j] = tolower(ns[j]);
                    } else if (x == 1) {
                        ns[j] = toupper(ns[j]);
                    }
                }
            }
            k = k2;
        }
    }

    cout << s << endl;
    cout << ns << endl;

    return 0;
}

RC-u2 桌游猜谜

分值: 20分

考点: 集合论(二进制) + 枚举技巧

题目其实相当的晦涩

  1. 选择3种颜色,并选择[L, R]范围,其 m i n ( K 1 , K 2 ) min(K_1, K_2) min(K1,K2) 最大化
  2. 最后求的结果为,在1的基础上, m a x ( K 1 , K 2 ) ∗ ( 8 − n ) 3 max(K_1, K_2) * (8-n)^3 max(K1,K2)(8n)3

这题难在阅读理解, T_T.

代码的话,其实分了2个阶段

  1. 二进制枚举划分集合
  2. 穷举各种可能性,然后枚举[L, R]区间的方案数
#include <bits/stdc++.h>

using namespace std;

int main() {
    int t;
    cin >> t;
    while (t-- > 0) {
        int n;
        cin >> n;
        vector<vector<bool>> vis(6, vector<bool>(9, false));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < 6; j++) {
                int v; cin >> v;
                vis[j][v] = true;
            }
        }

        int target = -1;
        int ans = 0;
        
        int range = 1 << 6;
        for (int i = 0; i < range; i++) {
            int cnt = __builtin_popcount(i);
            if (cnt != 3) continue;
            
            vector<int> stat(24 + 1);

            function<void(int,int,int)> dfs;
            dfs = [&](int s, int acc, int mask) {
                if (s == 6) {
                    stat[acc]++;
                    return;
                }
                if (((1 << s) & mask) != 0) {
                    dfs(s + 1, acc, mask);
                } else {
                    for (int j = 1; j <= 8; j++) {
                        if (!vis[s][j]) {
                            dfs(s + 1, acc + j, mask);
                        }
                    }
                }
            };

            dfs(0, 0, i);
            int pow3 = (8 - n) * (8 - n) * (8 - n); 

            // 枚举 L-R 
            for (int s = 0; s <= 24; s++) {
                int acc = 0;
                for (int e = s; e <= 24; e++) {
                    acc += stat[e];
                    int tmp = min(pow3 - acc, acc);
                    if (target < tmp) {
                        target = tmp;
                        ans = max(pow3 - acc, acc) * pow3;
                    }
                }
            }            
        }
        cout << ans << "\n";
    }
    return 0;
}

RC-u3 兰州拉面派餐系统

分值: 25分

思路: 模拟

这类调度模型题,其实很有技巧性

因为任务是一开始预定的,所以这题相对容易些

引入优先队列,对煮面篮子(worker)进行调度

需要注意的是

  1. 按是否空闲有限调度
  2. 都空闲的提前下,按编号大小调度
#include <bits/stdc++.h>

using namespace std;

struct E {
    int id; // 编号
    int at; // 时间点
    E() {}
    E(int id, int at) : id(id), at(at) {}
    bool operator<(const E& lhs) const {
        if (at != lhs.at) return at < lhs.at;
        return id < lhs.id;
    }
};

int main() {
    
    int n, m, q;
    cin >> n >> m >> q;
    vector<int> cost(n + 1);

    for (int i = 1; i <= n; i++) {
        cin >> cost[i];
    }
    
    // 用优先队列驱动,事件调度
    auto comp = [](auto &a, auto &b) { return b < a; };
    priority_queue<E, vector<E>, decltype(comp)> pq;
    for (int i = 1; i <= m; i++) pq.push(E(i, 0));
    
    vector<array<int, 2>> ans;
    vector<int> rec(m + 1, 0);
    for (int i = 1; i <= q; i++) {
        int v; cin >> v;
        E e = pq.top(); pq.pop();
        rec[e.id]++;
        ans.push_back({e.at + cost[v], i});
        pq.push(E(e.id, e.at+cost[v]));
    }
    
    sort(ans.begin(), ans.end());
    
    for (int i = 0; i < q; i++) {
        auto &e = ans[i];
        cout << e[1] << ":" << e[0] << " \n"[i == q - 1];
    }
    for (int i = 1; i <= m; i++) {
        cout << rec[i] << " \n"[i == m];
    }
    
    return 0;
}

RC-u4 拆积木

分值: 30 分

思路:拓扑排序

在这里插入图片描述

积木依赖于上下相邻关系,抓住这个关键点即可

这边需要使用到链式前向星来建图,不然最后2个case会MLE。

内存优化点:

  1. 滚动数组
  2. 链式前向星

#include <bits/stdc++.h>

using namespace std;

const int M = 1'000'000 + 5;

int idx = 0;
int h[M];
struct Edge {
    int to;
    int next;
} edges[M];
int degree[M];

void addEdge(int u, int v) {
    edges[idx].to = v;
    edges[idx].next = h[u];
    h[u] = idx;
    idx++;
}

int mat[2][M];

int main() {
    int n, m;
    cin >> n >> m;
    
    memset(h, -1, sizeof(int) * M);
    memset(degree, -1, sizeof(int) * M);
    
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> mat[i&1][j];
            int v = mat[i&1][j];
            if (degree[v] == -1) {
                degree[v] = 0;
                cnt++;
            }
            if (i > 0 && mat[1^(i&1)][j] != mat[i&1][j]) {
                addEdge(mat[1^(i&1)][j], mat[i&1][j]);
                degree[v]++;
            }
        }
    }
    
    priority_queue<int, vector<int>, greater<int>> pq;
    for (int i = 0; i < M; i++) {
        if (degree[i] == 0) {
            pq.push(i);
        }
    }
    
    vector<int> ans;
    while (!pq.empty()) {
        int u = pq.top(); pq.pop();
        ans.push_back(u);
        for (int i = h[u]; i != -1; i = edges[i].next) {
            int v = edges[i].to;
            if (--degree[v] == 0) {
                pq.push(v);
            }
        }
    }

    int rn = ans.size();
    if (cnt != ans.size()) {
        for (int i = 0; i < ans.size(); i++) {
            cout << ans[i] << " ";
        }
        cout << "Impossible\n";
    } else {
        for (int i = 0; i < ans.size(); i++) {
            cout << ans[i] << " \n"[i == ans.size() - 1];
        }
    }
    
    return 0;
}

RC-u5 栈与数组

分值: 30分

思路: 预处理, 二分+DP校验

对于 C 1 , C 2 的前 i 和 j 项, p r e [ i ] [ j ] , 其最终留下的数个数是确定的 对于C1,C2的前i和j项,pre[i][j], 其最终留下的数个数是确定的 对于C1C2的前ij项,pre[i][j],其最终留下的数个数是确定的

因此利用 O ( n ∗ m ) O(n*m) O(nm)来构建pre数组

后续的二分+DP校验,就相对容易了

本质就是检查

d p [ i − 1 ] [ j ] ∧ p r e [ i − 1 ] [ j ] + 1 ≤ t h r e s h o l d (1) dp[i - 1][j] \land pre[i-1][j] + 1 \le threshold \tag{1} dp[i1][j]pre[i1][j]+1threshold(1)
d p [ i ] [ j − 1 ] ∧ p r e [ i ] [ j − 1 ] + 1 ≤ t h r e s h o l d (2) dp[i][j - 1] \land pre[i][j - 1] + 1 \le threshold \tag{2} dp[i][j1]pre[i][j1]+1threshold(2)
( 1 ) , ( 2 ) 任意一个满足,同时 p r e [ i ] [ j ] ≤ t h r e s h o l d , 那么 d p [ i ] [ j ] = t r u e (1), (2) 任意一个满足,同时 pre[i][j] \le threshold, 那么 dp[i][j] = true (1),(2)任意一个满足,同时pre[i][j]threshold,那么dp[i][j]=true

这样整体的时间复杂度为

O ( n ∗ m ∗ l o g ( n + m ) ) O(n * m * log(n+m)) O(nmlog(n+m))

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

int main() {
    
    int t;
    cin >> t;
    while (t-- > 0) {
        int n, m, k;
        cin >> n >> m >> k;
        vector<int> c1(n), c2(m);
        for (int &x: c1) cin >> x;
        for (int &x: c2) cin >> x;
        
        // *) 
        // 预处理状态
        vector<vector<int>> pre(n+1, vector<int>(m + 1, inf));    
        fill(pre[0].begin(), pre[0].end(), 0);
        
        for (int i = 0; i <= n; i++) {
            map<int, int> cnt;
            int acc = 0;
            
            for (int j = 1; j <= i; j++) {
                int v = c1[j - 1];
                cnt[v]++;
                acc++;
                if (cnt[v] == k) {
                    cnt[v] = 0; // erase
                    acc -= k;
                }
            }
            pre[i][0] = acc;
            
            for (int j = 1; j <= m; j++) {
                int v = c2[j - 1];
                cnt[v]++;
                acc++;
                if (cnt[v] == k) {
                    cnt[v] = 0; // erase
                    acc -= k;
                }
                pre[i][j] = acc;
            }
        }

        function<bool(int)> check = [&](int up) {
            vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
            dp[0][0] = 1;
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= m; j++) {
                    if (i == 0 && j == 0) continue;
                    if (pre[i][j] > up) continue;
                    if (i - 1 >= 0 && pre[i - 1][j] + 1 <= up && dp[i - 1][j] == 1) dp[i][j] = 1;
                    if (j - 1 >= 0 && pre[i][j - 1] + 1 <= up && dp[i][j - 1] == 1) dp[i][j] = 1;
                }
            }
            return dp[n][m] == 1;
        };
        
        
        // 二分 + dp(布尔)
        int l = 1, r = n + m;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (check(mid)) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        cout << l << "\n";
    }
    
    return 0;
}


写在最后

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2383460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW风机状态实时监测

在当今电子设备高度集成化的时代&#xff0c;设备散热成为关键问题。许多大型设备机箱常采用多个风机协同散热&#xff0c;确保系统稳定运行。一旦风机出现故障&#xff0c;若不能及时察觉&#xff0c;可能导致设备损坏&#xff0c;造成巨大损失。为满足对机箱内风机状态实时监…

十一、面向对象底层逻辑-Dubbo过滤器Filter接口

一、引言&#xff1a;分布式系统中的可观测性与治理基石 在分布式服务调用链路中&#xff0c;如何在服务调用前后植入通用逻辑&#xff08;如日志记录、权限校验、性能监控等&#xff09;&#xff0c;是构建可观测、可治理系统的关键需求。Dubbo通过Filter接口实现了面向切面编…

linux安装nginx和前端部署vue项目

1、打包前端项目 npm run build 执行完后会在根目录下生成一个dist文件夹&#xff0c;这个dist文件夹就是我们后面要部署到nginx的东西。 2、将dist文件夹上传到服务器中 自己建一个目录&#xff0c;上传即可&#xff08;尽量不要在root目录下&#xff0c;可能涉及权限问题…

软件设计师“数据流图”真题考点分析——求三连

数据流图考点分析 1. 考点分值占比与趋势分析 综合知识题分值统计表 年份考题数量分值分值占比考察重点2018111.33%数据流图基本元素2019222.67%数据流图绘制原则2020111.33%数据流图与控制流图的区别2021334.00%数据字典与数据流图的关系2022222.67%分层数据流图的分解原则…

基于R语言的贝叶斯网络模型实践技术应用:开启科研新视角

在现代科研领域&#xff0c;变量间的因果关系推断是生态学、环境科学、医学等多学科研究的核心问题。然而&#xff0c;传统的统计学方法往往只能揭示变量间的相关关系&#xff0c;而非因果关系。贝叶斯网络作为一种结合图论与统计学理论的新型模型&#xff0c;不仅能够统合多种…

【Git】远程操作

Git 是一个分布式版本控制系统 可以简单理解为&#xff0c;每个人的电脑上都是一个完整的版本库&#xff0c;这样在工作时&#xff0c;就不需要联网 了&#xff0c;因为版本库就在自己的电脑上。 因此&#xff0c; 多个人协作的方式&#xff0c;譬如说甲在自己的电脑上改了文件…

DeepSpeed简介及加速模型训练

DeepSpeed是由微软开发的开源深度学习优化框架&#xff0c;专注于大规模模型的高效训练与推理。其核心目标是通过系统级优化技术降低显存占用、提升计算效率&#xff0c;并支持千亿级参数的模型训练。 官网链接&#xff1a;deepspeed 训练代码下载&#xff1a;git代码 一、De…

openlayer:10点击地图上某些省份利用Overlay实现提示省份名称

实现点击地图上的省份&#xff0c;在点击经纬度坐标位置附近利用Overlay实现提示框提示相关省份名称。本文介绍了如何通过OpenLayers库实现点击地图上的省份&#xff0c;并在点击的经纬度坐标位置附近显示提示框&#xff0c;提示相关省份名称。首先&#xff0c;定义了两个全局变…

upload-labs通关笔记-第13关 文件上传之白名单POST法

目录 一、白名单过滤 二、%00截断 1.截断原理 2、截断条件 &#xff08;1&#xff09;PHP版本 < 5.3.4 &#xff08;2&#xff09;magic_quotes_gpc配置为Off &#xff08;3&#xff09;代码逻辑存在缺陷 三、源码分析 1、代码审计 &#xff08;1&#xff09;文件…

数据库健康监测器(BHM)实战:如何通过 HTML 报告识别潜在问题

在数据库运维中,健康监测是保障系统稳定性与性能的关键环节。通过 HTML 报告,开发者可以直观查看数据库的运行状态、资源使用情况与潜在风险。 本文将围绕 数据库健康监测器(Database Health Monitor, BHM) 的核心功能展开分析,结合 Prometheus + Grafana + MySQL Export…

Oracle 11g 单实例使用+asm修改主机名导致ORA-29701 故障分析

解决 把服务器名修改为原来的&#xff0c;重启服务器。 故障 建表空间失败。 分析 查看告警日志 ORA-1119 signalled during: create tablespace splex datafile ‘DATA’ size 2000M… Tue May 20 18:04:28 2025 create tablespace splex datafile ‘DATA/option/dataf…

OpenCV CUDA模块图像过滤------用于创建一个最大值盒式滤波器(Max Box Filter)函数createBoxMaxFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 createBoxMaxFilter()函数创建的是一个 最大值滤波器&#xff08;Maximum Filter&#xff09;&#xff0c;它对图像中每个像素邻域内的像素值取最…

Redis数据库-消息队列

一、消息队列介绍 二、基于List结构模拟消息队列 总结&#xff1a; 三、基于PubSub实现消息队列 (1)PubSub介绍 PubSub是publish与subscribe两个单词的缩写&#xff0c;见明知意&#xff0c;PubSub就是发布与订阅的意思。 可以到Redis官网查看通配符的书写规则&#xff1a; …

破解充电安全难题:智能终端的多重防护体系构建

随着智能终端的普及&#xff0c;充电安全问题日益凸显。从电池过热到短路起火&#xff0c;充电过程中的安全隐患不仅威胁用户的生命财产安全&#xff0c;也制约了行业的发展。如何构建一套高效、可靠的多重防护体系&#xff0c;成为破解充电安全难题的关键。通过技术创新和系统…

apptrace 三大策略,助力电商 App 在 618 突围

随着 5 月 13 日 “618” 电商大促预售战的打响&#xff0c;各大平台纷纷祭出百亿补贴、消费券等大招&#xff0c;投入超百亿流量与数十亿现金&#xff0c;意图在这场年度商战中抢占先机。但这场流量争夺战远比想象中艰难&#xff0c;中国互联网络信息中心数据显示&#xff0c;…

SuperVINS:应对挑战性成像条件的实时视觉-惯性SLAM框架【全流程配置与测试!!!】【2025最新版!!!!】

一、项目背景及意义 SuperVINS是一个改进的视觉-惯性SLAM&#xff08;同时定位与地图构建&#xff09;框架&#xff0c;旨在解决在挑战性成像条件下的定位和地图构建问题。该项目基于经典的VINS-Fusion框架&#xff0c;但通过引入深度学习方法进行了显著改进。 视觉-惯性导航系…

Node-Red通过开疆智能Profinet转ModbusTCP采集西门子PLC数据配置案例

一、内容简介 本篇内容主要介绍Node-Red通过node-red-contrib-modbus插件与开疆智能ModbusTCP转Profinet设备进行通讯&#xff0c;这里Profinet转ModbusTCP网关作为从站设备&#xff0c;Node-Red作为主站分别从0地址开始读取10个线圈状态和10个保持寄存器&#xff0c;分别用Mo…

【性能测试】jvm监控

使用本地jvisualvm远程监控服务器 参考文章&#xff1a;https://blog.csdn.net/yeyuningzi/article/details/140261411 jvisualvm工具默认是监控本地jvm&#xff0c;如果需要监控远程就要修改配置参数 1、先查看是否打开 ps -ef|java 如果打开杀掉进程 2、进入项目服务路径下…

Uniapp开发鸿蒙应用时如何运行和调试项目

经过前几天的分享&#xff0c;大家应该应该对uniapp开发鸿蒙应用的开发语法有了一定的了解&#xff0c;可以进行一些简单的应用开发&#xff0c;今天分享一下在使用uniapp开发鸿蒙应用时怎么运行到鸿蒙设备&#xff0c;并且在开发中怎么调试程序。 运行 Uniapp项目支持运行到…

QT+RSVisa控制LXI仪器

1.下载并安装visa R&SVISA - Rohde & Schwarz China 2.安装后的目录说明 安装了64位visa会默认把32位的安装上&#xff1b; 64位库和头文件目录为&#xff1a;C:\Program Files\IVI Foundation 32位库和头文件目录为&#xff1a;C:\Program Files (x86)\IVI Foundation…