当前位置: 首页 > news >正文

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

前言

在这里插入图片描述


题解

2025年睿抗机器人开发者大赛CAIP-编程技能赛(省赛)
RoboCom 世界机器人开发者大赛-本科组

t5真的是满满地回忆,这游戏n久年前写过,我记得当时用了一种2.5D的技巧,来实现2维图形实现伪3D的效果。

整体真不难,纯算法的含量低于前几年,但码量真的不小。

pta平台2025年省赛本科组真题

在这里插入图片描述


RC-u1 早鸟价

分数: 10分
题型: 签到


#include <bits/stdc++.h>using namespace std;int main() {int n;cin >> n;for (int i = 0; i < n; i++) {int m, d, c;cin >> m >> d >> c;if (m > 7 || (m == 7 && d > 11)) {cout << "Too late!\n";} else if (m == 7 || (m == 6 && d > 20)) {if (c > 2000) {cout << "^_^\n";} else if (c == 2000) {cout << "Ok!\n";} else {cout << "Need more!\n";}} else {if (c > 1800) {cout << "^_^\n";} else if (c == 1800) {cout << "Ok!\n";} else {cout << "Need more!\n";}}}return 0;
}

注: 需要注意tuple类元素 大小比较 的细节,多元的时候,最好写成类,然后重载< 操作符。


RC-u2 谁进线下了?III

分数: 15
题型:签到
感觉这题,比t1更加的签到, 纯阅读理解


#include <bits/stdc++.h>using namespace std;int main() {int t;cin >> t;while (t-- > 0) {int n, s;cin >> n >> s;int one = 0, tot = 0;for (int i = 0; i < n; i++) {int r, c;cin >> r >> c;if (r==1) {one++;}tot += c;}int r1 = 0, r2 = 0;if (one >= (n + 1) / 2) r1 = 1;if (tot >= s + 50) r2 = 1;cout << r1 << " " << r2 << "\n";}return 0;
}

RC-u3 点格棋

分数: 20
思路: 枚举 + 模拟

在这里插入图片描述
需要理顺不合符条件的步骤

  • 点和边限制
  1. (x1, y1) 和 (x2, y2) 数据不合法,包括越界
  2. (x1, y1) 和 (x2, y2) 两点不是水平/垂直相邻
  3. 重复添加连边
  • 轮换次序限制
  1. 没有按照玩家的轮换次序,获得奖励会保持操作,不得分会轮换
  2. 小A先行
  3. 得分相等,则小B获胜

而对于边,根据方向,采用水平和垂直二维数组来维护。

#include <bits/stdc++.h>using namespace std;int main() {int n, m, s;cin >> n >> m >> s;vector<vector<int>> h(n, vector<int>(m));vector<vector<int>> v(m, vector<int>(n));// 当前走的玩家int side = 0;int as = 0, bs = 0;// 记录错误的操作编号vector<int> wrong;for (int i = 0; i < s; i++) {int p, y1, x1, y2, x2;cin >> p >> y1 >> x1 >> y2 >> x2;y1--; x1--; y2--; x2--;bool c1 = (y1 < 0 || y1 >= n) || (x1 < 0 || x1 >= m);bool c2 = (y2 < 0 || y2 >= n) || (x2 < 0 || x2 >= m);if (c1 || c2) {wrong.push_back(i);continue;}// 不是预期的玩家if (p != side) {wrong.push_back(i);continue;}bool flag = false;if (y1 == y2 && abs(x1 - x2) == 1) {if (x1 > x2) swap(x1, x2);if (h[y1][x1] == 1) {wrong.push_back(i);continue;}h[y1][x1] = 1;if (y1 > 0 && h[y1 - 1][x1] == 1 && v[x1][y1 - 1] == 1 && v[x2][y1 - 1] == 1) {if (p == 0) as++; else bs++;flag = true;}if (y1 + 1 < n && h[y1 + 1][x1] == 1 && v[x1][y1] == 1 && v[x2][y1] == 1) {if (p == 0) as++; else bs++;flag = true;}} else if (x1 == x2 && abs(y1 - y2) == 1) {if (y1 > y2) swap(y1, y2);if (v[x1][y1] == 1) {wrong.push_back(i);continue;}v[x1][y1] = 1;if (x1 > 0 && v[x1 - 1][y1] == 1 && h[y1][x1 - 1] == 1 && h[y1+1][x1 - 1] == 1) {if (p == 0) as++; else bs++;flag = true;}if (x1 + 1 < m && v[x1 + 1][y1] == 1 && h[y1][x1] == 1 && h[y1+1][x1] == 1) {if (p == 0) as++; else bs++;flag = true;}} else {wrong.push_back(i);continue;}if (!flag) side = 1 - side;}if (wrong.empty()) {cout << -1 << "\n";} else {for (int i = 0; i < wrong.size(); i++) {cout << (wrong[i] + 1) << " \n"[i == wrong.size() - 1];}}if (as > bs) {cout << 0 << " " << as << "\n";} else {cout << 1 << " " << bs << "\n";}return 0;
}

RC-u4 Tree Tree 的

分数: 25
思路:找圈

在这里插入图片描述
本题的核心,就是理解1,2两条件

从特殊到一般,其实可以手玩几个特殊的图形

  1. 菊花图
  2. 完全图

然后玩着玩着,你就会发现:
只有圈(圆),才满足这些特殊条件(n≥3)只有圈(圆), 才满足这些特殊条件(n\ge 3)只有圈(圆),才满足这些特殊条件(n3)
所以本题,就是给你一个无向图,然后寻找一个圈

需要特别注意:

  1. 空集和单点是特殊的G′G'G
  2. 2个节点以及彼此相连的边,也构成一个特殊的G′G'G

这边其实有两个思路:

  1. 二进制枚举参与圈的节点,然后dfs找圈
  2. 直接dfs找圈

时间复杂度评估: O(n∗4n)O(n * 4^{n})O(n4n), n≤10,题目保证一个节点最多4条边n \le 10, 题目保证一个节点最多4条边n10,题目保证一个节点最多4条边

#include <bits/stdc++.h>using namespace std;bool dfs(int u, int start, vector<vector<int>> &g, int mask, int state) {if (state == mask) {for (int v: g[u]) {if (v == start) {return true;}}return false;}for (int v: g[u]) {if (((1 << v) & mask) != 0 && ((1 << v) & state) == 0) {if (dfs(v, start, g, mask, state | (1 << v))) {return true;}}}return false;
}int main() {int t;cin >> t;while (t-- > 0) {int n, m;cin >> n >> m;vector<vector<int>> g(n);for (int i = 0; i < m; i++) {int u, v;cin >> u >> v;u--; v--;g[u].push_back(v);g[v].push_back(u);}set<int> tree = {0, 1};if (m >= 1) {tree.insert(2);}// 枚举二进制的子集int range = 1 << n;for (int i = 1; i < range; i++) {int cnt = 0;// 需要一个起点,以及集合的大小int start = -1;for (int j = 0; j < n; j++) {if ((i & (1 << j)) != 0) {if (start == -1) start = j;cnt++;}}// 避免相同的集合大小if (tree.find(cnt) == tree.end()) {if (dfs(start, start, g, i, 1 << start)) {tree.insert(cnt);}}}// 逆序拿到2个最大, 次大的结果auto iter = tree.rbegin();cout << *iter << " ";iter++;cout << *iter << "\n";}return 0;
}

直接dfs找圈

#include <bits/stdc++.h>using namespace std;struct Solution {vector<bool> vis;vector<vector<int>> g;int n, m;void solve() {cin >> n >> m;g.resize(n);vis.resize(n + 1);for (int i = 0; i < m; i++) {int u, v;cin >> u >> v;u--; v--;g[u].push_back(v);g[v].push_back(u);}vis[0] = vis[1] = true;if (m > 0) vis[2] = true;for (int i = 0; i < n; i++) {dfs(i, i, 1 << i, 1);}int s1 = -1, s2 = -1;for (int i = n; i >= 0; i--) {if (vis[i]) {if (s1 == -1) s1 = i;else if (s2 == -1) s2 = i;}}cout << s1 << " " << s2 << "\n";}void dfs(int u, int s, int mask, int cnt) {for (int v: g[u]) {if (v == s) {vis[cnt] = true;continue;}if (((1 << v) & mask) == 0) {dfs(v, s, mask | (1 << v), cnt + 1);}}}    
};int main() {int t;cin >> t;while (t-- > 0) {Solution solution;solution.solve();}return 0;
}

RC-u5 游戏设计师

分数: 30
思路: 逆向思维+bfs+离线查询
在这里插入图片描述
可以引入状态 (x, y, s) 表示在(x, y)基准坐标,以s状态,最少需要多少步。

可以从空洞出发,进行一遍bfs,把所有的结果前提保存。
而后续的在线查询,就变成O(1)O(1)O(1)

#include <bits/stdc++.h>using namespace std;const int N = 1000;
int dp[3][N][N];struct E {int x, y, s;
};bool support(char c1, char c2) {if (c1 == '0' || c1 == '3') return false;if (c2 == '0' || c2 == '3') return false;return true;
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int n, m;cin >> n >> m;vector<string> g(n);int tx = -1, ty = -1;for (int i = 0; i < n; i++) {cin >> g[i];for (int j = 0; j < m; j++) {if (g[i][j] == '3') {tx = i;ty = j;}}}memset(dp, -1, sizeof(dp));deque<E> que;que.push_back({tx, ty, 0});dp[0][tx][ty] = 0;while (!que.empty()) {E e = que.front(); que.pop_front();if (e.s == 0) {if (e.y + 2 < m) {if (support(g[e.x][e.y + 1], g[e.x][e.y + 2])) {if (dp[1][e.x][e.y + 1] == -1|| dp[1][e.x][e.y + 1] > dp[0][e.x][e.y] + 1) {dp[1][e.x][e.y + 1] = dp[0][e.x][e.y] + 1;que.push_back({e.x, e.y + 1, 1});}}}if (e.y - 2 >= 0) {if (support(g[e.x][e.y - 1], g[e.x][e.y - 2])) {if (dp[1][e.x][e.y - 2] == -1|| dp[1][e.x][e.y - 2] > dp[0][e.x][e.y] + 1) {dp[1][e.x][e.y - 2] = dp[0][e.x][e.y] + 1;que.push_back({e.x, e.y - 2, 1});}}}if (e.x + 2 < n) {if (support(g[e.x + 1][e.y], g[e.x + 2][e.y])) {if (dp[2][e.x + 1][e.y] == -1|| dp[2][e.x + 1][e.y] > dp[0][e.x][e.y] + 1) {dp[2][e.x + 1][e.y] = dp[0][e.x][e.y] + 1;que.push_back({e.x + 1, e.y, 2});}}}if (e.x - 2 >= 0) {if (support(g[e.x - 2][e.y], g[e.x - 1][e.y])) {if (dp[2][e.x - 2][e.y] == -1|| dp[2][e.x - 2][e.y] > dp[0][e.x][e.y] + 1) {dp[2][e.x - 2][e.y] = dp[0][e.x][e.y] + 1;que.push_back({e.x - 2, e.y, 2});}}}} else if (e.s == 1) {if (e.y + 2 < m) {if (g[e.x][e.y + 2] == '1') {if (dp[0][e.x][e.y + 2] == -1|| dp[0][e.x][e.y + 2] > dp[1][e.x][e.y] + 1) {dp[0][e.x][e.y + 2] = dp[1][e.x][e.y] + 1;que.push_back({e.x, e.y + 2, 0});}}}if (e.y - 1 >= 0) {if (g[e.x][e.y - 1] == '1') {if (dp[0][e.x][e.y - 1] == -1|| dp[0][e.x][e.y - 1] > dp[1][e.x][e.y] + 1) {dp[0][e.x][e.y - 1] = dp[1][e.x][e.y] + 1;que.push_back({e.x, e.y - 1, 0});}}}if (e.x + 1 < n) {if (support(g[e.x + 1][e.y], g[e.x + 1][e.y + 1])) {if (dp[1][e.x + 1][e.y] == -1|| dp[1][e.x + 1][e.y] > dp[1][e.x][e.y] + 1) {dp[1][e.x + 1][e.y] = dp[1][e.x][e.y] + 1;que.push_back({e.x + 1, e.y, 1});}}}if (e.x - 1 >= 0) {if (support(g[e.x - 1][e.y], g[e.x - 1][e.y + 1])) {if (dp[1][e.x - 1][e.y] == -1|| dp[1][e.x - 1][e.y] > dp[1][e.x][e.y] + 1) {dp[1][e.x - 1][e.y] = dp[1][e.x][e.y] + 1;que.push_back({e.x - 1, e.y, 1});}}}} else {//if (e.y + 1 < m) {if (support(g[e.x][e.y + 1], g[e.x + 1][e.y + 1])) {if (dp[2][e.x][e.y + 1] == -1|| dp[2][e.x][e.y + 1] > dp[2][e.x][e.y] + 1) {dp[2][e.x][e.y + 1] = dp[2][e.x][e.y] + 1;que.push_back({e.x, e.y + 1, 2});}}}if (e.y - 1 >= 0) {if (support(g[e.x][e.y - 1], g[e.x + 1][e.y - 1])) {if (dp[2][e.x][e.y - 1] == -1|| dp[2][e.x][e.y - 1] > dp[2][e.x][e.y] + 1) {dp[2][e.x][e.y - 1] = dp[2][e.x][e.y] + 1;que.push_back({e.x, e.y - 1, 2});}}}if (e.x + 2 < n) {if (g[e.x + 2][e.y] == '1') {if (dp[0][e.x + 2][e.y] == -1|| dp[0][e.x + 2][e.y] > dp[2][e.x][e.y] + 1) {dp[0][e.x + 2][e.y] = dp[2][e.x][e.y] + 1;que.push_back({e.x + 2, e.y, 0});}}}if (e.x - 1 >= 0) {if (g[e.x - 1][e.y] == '1') {if (dp[0][e.x - 1][e.y] == -1|| dp[0][e.x - 1][e.y] > dp[2][e.x][e.y] + 1) {dp[0][e.x - 1][e.y] = dp[2][e.x][e.y] + 1;que.push_back({e.x - 1, e.y, 0});}}}}}int q;cin >> q;while (q-- > 0) {int x, y, s;cin >> x >> y >> s;x--; y--;cout << dp[s][x][y] << "\n";}return 0;
}

这类题,全靠细心了,T_T


写在最后

在这里插入图片描述

http://www.dtcms.com/a/278335.html

相关文章:

  • Python 变量与简单输入输出:从零开始写你的第一个交互程序
  • 【Java入门到精通】(四)Java语法进阶
  • 动手学深度学习——线性回归的从零开始实现
  • 【记录】BLE|百度的旧蓝牙随身音箱手机能配对不能连接、电脑能连接不能使用的解决思路(Wireshark捕获并分析手机蓝牙报文)
  • 1.2.2 高级特性详解——AI教你学Django
  • 【图片识别改名】水印相机拍的照片如何将照片的名字批量改为水印内容?图片识别改名的详细步骤和注意事项
  • 【WPF】WPF 自定义控件 实战详解,含命令实现
  • 【零基础入门unity游戏开发——unity3D篇】3D光源之——unity6的新功能Adaptive Probe Volumes(APV)(自适应探针体积)
  • ACL流量控制实验
  • 深入了解linux系统—— 进程信号的产生
  • 客户端主机宕机,服务端如何处理 TCP 连接?详解
  • EasyExcel实现Excel文件导入导出
  • VScode链接服务器一直卡在下载vscode服务器,无法连接成功
  • C++之哈希表的基本介绍以及其自我实现(开放定址法版本)
  • 多客户端 - 服务器结构-实操
  • 史上最清楚!读者,写者问题(操作系统os)
  • 基于 Gitlab、Jenkins与Jenkins分布式、SonarQube 、Nexus 的 CiCd 全流程打造
  • SQL创建三个表
  • 从 JSON 到 Python 对象:一次通透的序列化与反序列化之旅
  • Dubbo高阶难题:异步转同步调用链上全局透传参数的丢失问题
  • Selenium动态网页爬虫编写与解释
  • 【微信小程序】
  • 当你在 Git 本地提交后,因权限不足无法推送到服务端,若想撤销本次提交,可以根据不同的需求选择合适的方法,下面为你介绍两种常见方式。
  • 清除 Android 手机 SIM 卡数据的4 种简单方法
  • 云手机常见问题解析:解决延迟、掉线等困扰
  • 云手机的多重用途:从游戏挂机到办公自动化
  • kafka的部署
  • 从零实现浏览器摄像头控制与视频录制:基于原生 JavaScript 的完整指南
  • 如何将数据从一部手机传输到另一部手机?
  • 马蹄集 BD202401补给