ccf-csp #201903-4 消息传递接口
2020-04-07 18:29
1066 查看
题目链接:http://118.190.20.162/view.page?gpid=T86
题目思路
第一次看这道题的时候,感觉像是仅可以可在左边这个面操作的消消乐。然后每一行可以用一个队列来存储,当该行第一个元素被消掉后,只需要把它push出来就可以了。
由于思路存在以下问题,最后还是参考了别人的博客。
- 如何动态创建那么多队列(当时还没写过队列数组) ?
- 如何去模拟这个消除的过程,有什么通用的方法寻找可以消掉的两个元素?
- 如何判断当前状态能否继续消下去?
看了dalao的博客后,有了以下思路:
- 通过队列数组来存储各个进程,每次挑选一个指令不为空的进程(preprepre),通过读取进程队列的第一个指令等待的进程编号决定下一个要访问进程(nextnextnext)。
- 当 nextnextnext 要访问的进程恰好是 preprepre ,且他们分别为R和S,则把它们消掉。否则,把当前访问的进程标志为preprepre,然后 把 nextnextnext 置为 preprepre 的第一个指令等待的进程编号(类似于链表访问下一个元素的操作)。
- 当所有的进程队列都为空时结束模拟。
- 至于死锁判断,当等待的进程已经访问过且同为R或S(说明出现了环),或者等待的进程其指令已经为空(等待不会出现的东西),说明出现了死锁。
代码如下
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e4 + 10; struct Node { // id表示要访问进程的id int id, sr; }; int T, n; string str; queue<Node> q[maxn]; // q[i]表示第i号进程 int vis[maxn]; //用于检测有没有环(死锁) void init() { for (int j = 0; j < n; j++) { getline(cin, str); for (int i = 0; i < str.length(); i++) { Node node; node.sr = (str[i++] == 'R' ? 1 : 0); int t = 0; while (i < str.length() && str[i] != ' ') t = t * 10 + str[i++] - '0'; node.id = t; q[j].push(node); } } } void solve() { int flag = 1; while (flag) { flag = 0; memset(vis, 0, sizeof(vis)); int pre = 0; while (pre < n && q[pre].empty()) pre++; if (pre == n) break; int next = q[pre].front().id; vis[pre] = 1; // 当访问已经访问过或者已经没有指令的进程,说明出现死锁。 while (!vis[next] && !q[next].empty()) { vis[next] = 1; // 满足消除条件 if (q[next].front().id == pre && q[next].front().sr != q[pre].front().sr) { flag = 1; q[next].pop(); q[pre].pop(); break; } // 类似于链表访问一下元素的操作 pre = next; next = q[pre].front().id; } } int ans = 0; for (int i = 0; i < n; i++) { //如果进程指令不为空,说明出现死锁 if (!q[i].empty()) { ans = 1; // 进程指令的清空操作 while (!q[i].empty()) q[i].pop(); } } printf("%d\n", ans); } int main() { //freopen("1.in", "r", stdin); scanf("%d %d", &T, &n); getchar(); while (T--) { init(); solve(); } return 0; }
最后,还是谈谈踩到的坑:
- 需要把首行输入T和n的值后面的’\n’用getchar()清掉,不然会影响后面getline()的读入。
- 把进程中的指令分离时,要注意检查语句逻辑的正确性。
- 如果用set或map记录进程有没有被访问过就会超时,改成普通的数组不会超时(耗时:906ms,感觉有点勉强)。
- 差点忽略了“等待的进程其指令已经为空”这种情况。
参考博客:CSP 201903-4 消息传递接口(模拟题) 满分
- 点赞 3
- 收藏
- 分享
- 文章举报
相关文章推荐
- ccf-csp #201912-1 报数
- PHP7 安装 memcache
- 高校学生领取云服务器教程
- CentOS7安装wdCP面板,快速搭建web运行环境(图文详解)
- 剑指Offer #10 矩形覆盖(问题分析)
- 「软件测试基础」理论篇之软件测试概论
- wdCP面板升级MySQL版本为5.6
- Java基础之JDK 8下载、安装和环境变量配置
- 面试官问你HTTP状态码,你敢答吗?
- 手撕设计模式之单例模式(详细解析)
- Java的Arrays.sort()良心总结
- Spring Boot实现简单的用户权限管理(超详细版)
- HDU - 1716无需思考暴力做法
- C++ STL容器总结之vector(超详细版)
- 达摩院悬壶,看医疗 AI 如何济世
- 做了那么多架构,你真的懂 SOA 了吗?
- 前端生产方式:过去 10 年回顾和未来 10 年展望
- 如何让页面动起来?支付宝2020新春红包前端3D技术揭秘
- 阿里和浙大的“AI 训练师助手”是这样炼成的
- 以阿里云RPA为例,来告诉你到底RPA是什么?