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

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


前言

在这里插入图片描述


题解

今日心血来潮,试了下2024年睿抗CAIP的本科组(省赛),2个小时而言,感觉难度适中。

如果亲们要准备睿抗算法赛,可以试试 牛客周赛 & 蓝桥杯周赛,和这个难度差不多,但是可能睿抗算法赛码量更大一些。

在这里插入图片描述

3个模拟题 + 1个图论 + 动态规划, 后三题已经兼具一定思维。


RC-u1 热҈热҈热҈

分值: 10分

题型: 模拟题

题意: 统计一个数组中,大于等于35的个数(需要过滤某个同余的项)

#include<bits/stdc++.h>using namespace std;int main() {int n, w;cin >> n >> w;int ans = 0, ans2 = 0;for (int i = 0; i < n; i++) {int v;cin >> v;if (v >= 35) {if (w == 4) ans2++;else ans++;}w = (w + 1) >= 8 ? 1 : w + 1;}cout << ans << " " << ans2 << endl;return 0;
}

RC-u2 谁进线下了?

分值: 15分

题型: 模拟

题意: 给予不同排名不同的分值,同时一个kill的得分,统计最终每个队伍的得分

#include <bits/stdc++.h>using namespace std;int rank_score(int r) {if (r == 1) return 12;else if (r == 2) return 9;else if (r == 3) return 7;else if (r == 4) return 5;else if (r == 5) return 4;else if (r >= 6 && r <= 7) return 3;else if (r >= 8 && r <= 10) return 2;else if (r >= 11 && r <= 15) return 1;return 0;
}int main() {int t;cin >> t;vector<int> arr(20, 0);while (t-- > 0) {for (int i = 0; i < 20; i++) {int r, k;cin >> r >> k;arr[i] += rank_score(r) + k;}}for (int i = 0; i < 20; i++) {cout << (i + 1) << " " << arr[i] << '\n';}return 0;
}

RC-u3 暖炉与水豚

分值: 20分

题型: 模拟

题意: 其实该题应该来自于 扫雷,然后显示的数字反推 未确定的格子,只不过这边用了可爱的青蛙。

这边的模拟,已经带上一定的思维了,而且代码量不少。

从最多只有一个 反常的青蛙(温暖的青蛙,但是周边没暖炉)出发,这样遍历的格子最多8个。

然后在check,用cold的青蛙去验证这个格子是否满足需求。

#include <bits/stdc++.h>using namespace std;// 按特定的顺序排列,已经特定的顺序枚举
int dirs[8][2] = {{-1, -1}, {0,-1}, {1,-1},{-1, 0}, {1, 0},{-1, 1}, {0,1}, {1,1},
};bool check(vector<string> &g, int r, int c) {int n = g.size(), m = g[0].size();for (int i = 0; i < 8; i++) {int y = r + dirs[i][0];int x = c + dirs[i][1];if (y>=0&&y<n && x>=0 &&x<m) {if (g[y][x] == 'm') return false;}}return true;
}bool verify(vector<string> &g, int r, int c) {int n = g.size(), m = g[0].size();for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (g[i][j]=='c') {if (abs(r - i) <= 1 && abs(c - j) <=1) {return false;}}}}return true;
}int main() {// 需要优化, r, cint n, m;cin >> n >> m;vector<string> g(n);for (int i = 0; i < n;i ++) {cin >> g[i];}// 找特殊的位子vector<array<int, 2>> ans;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (g[i][j] == 'w' && check(g, i, j)) {for (int k = 0; k < 8; k++) {int y = i + dirs[k][1];int x = j + dirs[k][0];if (y>=0&&y<n && x>=0 &&x<m && g[y][x] == '.') {if (verify(g, y, x)) {ans.push_back({y + 1, x + 1});}}}break;}}}if (ans.size() == 0) {cout << "Too cold!" << endl;} else {for (auto &e: ans) {cout << e[0] << " " << e[1] << endl;}}return 0;
}

RC-u4 章鱼图的判断

分值: 25

题型: 图论

这边的章鱼图很有意思,要么是环,要么是基环树

基环树,就用经典的拓扑排序求解

需要注意这题,属于森林,因此这次属于入门的图论题,但是码量不小。

思路:

  1. 通过bfs,找出连通图
  2. 对于每个连通图,通过拓扑排序技巧,去掉分枝(链/树), 再判断剩下是否是环(所有节点度都是2)
#include <bits/stdc++.h>using namespace std;vector<int> bfs(vector<vector<int>> &g, int v, vector<int> &vis) {vector<int> graph;deque<int> que;que.push_back(v);vis[v] = 1;graph.push_back(v);while (!que.empty()) {int u = que.front(); que.pop_front();for (int v: g[u]) {if (vis[v] == 0) {vis[v] = 1;que.push_back(v);graph.push_back(v);}}}return graph;
}int topology(vector<vector<int>> &g, vector<int> &deg, vector<int> &graph) {deque<int> que;for (int &u: graph) {if (deg[u] == 1) {que.push_back(u);}}while (!que.empty()) {int u = que.front(); que.pop_front();for (int v: g[u]) {if (--deg[v] == 1) {que.push_back(v);}}}int cnt = 0;for (int u: graph) {if (deg[u] > 2) return -1;if (deg[u] == 2) cnt++;}return cnt;
}int main() {int t;cin >> t;while (t-- > 0) {int n, m;cin >> n >> m;vector<int> deg(n);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);deg[u]++;deg[v]++;}int max = 0;int ans = 0;vector<int> vis(n);for (int i = 0; i < n;i ++) {if (vis[i] == 0) {vector<int> graph = bfs(g, i, vis);int tmp = topology(g, deg, graph);if (tmp > 0) {max = tmp;ans++;}}}if (ans == 1) {cout << "Yes " << max << endl;} else {cout << "No " << ans << endl;}}return 0;
}

RC-u5 工作安排

分值: 30
题型: 需要思维的DP

这种类型的题,往往和贪心有关,挺难处理的。

这边是基于贪心策略,来保证dp的无后效性。

按截止时间排序每个task,然后按
d p [ i ] [ j ] , i 为前 i 个 t a s k , j 为时间点,值为最多的收益 dp[i][j], i为前i个task,j为时间点,值为最多的收益 dp[i][j],i为前itaskj为时间点,值为最多的收益

然后转移方程为

d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j − t a s k [ i ] . t ] + t a s k [ i ] . p ) dp[i][j] = max (dp[i - 1][j - task[i].t] + task[i].p) dp[i][j]=max(dp[i1][jtask[i].t]+task[i].p)
t a s k [ i ] . t ≤ j ≤ t a k s [ i ] . t + t a s k [ i ] . d task[i].t \le j \le taks[i].t + task[i].d task[i].tjtaks[i].t+task[i].d

最终结果为

m a x d p [ i ] [ j ] max {dp[i][j]} maxdp[i][j]

这边可以借助 前缀和的技巧 来优化,同时这边需要使用滚动数组的技巧

不然会遇到 内存溢出的错误

#include <bits/stdc++.h>using namespace std;struct Span {int t, d, p;Span(int t, int d, int p) : t(t), d(d), p(p) {}
};void solve() {int n;cin >> n;vector<Span> ps;for (int i = 0; i < n; i++) {int t, d, p; cin >> t >> d >> p;ps.push_back(Span(t, d, p));}// 按时间序排序,保证dp的无后效性sort(ps.begin(), ps.end(), [](auto &a, auto &b) {return a.d < b.d;});// 这边的5000为时间的上限vector<int> dp(5001, 0);for (int i = 0; i < n; i++) {vector<int> dp2(5001, 0);int d = ps[i].d, t = ps[i].t;for (int j = 0; j <= d - t; j++) {dp2[j + t] = max(dp2[j + t], dp[j] + ps[i].p);}for (int j = 0; j <= 5000; j++) {dp2[j] = max(dp2[j], dp[j]);if (j > 0) dp2[j] = max(dp2[j], dp2[j - 1]);}dp.swap(dp2);}cout << dp[5000] << endl;}int main() {int t;cin >> t;while (t-- > 0) {solve();}return 0;
}

写在最后

在这里插入图片描述

相关文章:

  • Zabbix Agent的区别与选择!
  • 鸿蒙OSUniApp制作自定义的下拉菜单组件(鸿蒙系统适配版)#三方框架 #Uniapp
  • 阿里巴巴 1688 数据接口开发指南:构建自动化商品详情采集系统
  • 【RabbitMQ】实现RPC通信的完整指南
  • MySQL——1、数据库基础
  • 25.5.15
  • homeassistant安装
  • 社区电商场景的 社群推广与维护系统化分析框架
  • MySQL如何查看某个表所占空间大小?(表空间大小查看方法)
  • 《教育退费那些事儿:从困境到破局》
  • 中国版 Cursor?腾讯推出 AI 编程助手 CodeBuddy,重新定义编程体验
  • 硅基计划2.0 学习总结 贰
  • 软件工程之软件产品的环境
  • 在文件检索方面doris和elasticsearch的区别
  • 最新版VSCode通过SSH远程连接Ubuntu 16.04等旧版Linux的方法
  • 中国近代史3
  • 阿里开源通义万相 Wan2.1-VACE,开启视频创作新时代
  • 【工具】metaTP:一种集成了自动化工作流程的元转录组数据分析工具包
  • git 本地提交后修改注释
  • YOLO11解决方案之距离计算探索
  • 第一集|好饭不怕晚,折腰若如初见
  • 普京确定俄乌谈判俄方代表团名单
  • 张涌任西安市委常委,已卸任西安市副市长职务
  • 当代科技拟召开债券持有人会议 ,对“H20科技2”进行四展
  • 美国务卿鲁比奥将前往土耳其参加俄乌会谈
  • 学者的“好运气”:读本尼迪克特·安德森《椰壳碗外的人生》