我的A-C题解和心路历程 # Accepted极限代码巅峰赛

news/2024/11/6 2:00:45/文章来源:https://www.cnblogs.com/cmyg/p/18529138

https://ac.nowcoder.com/acm/contest/91849

多年退役找工作选手膜拜众出题大佬!!!出的题特别好!!!

A

寻找分开的若干个11..1串,比如串001110001111,就是1111111

首先,认为所有的0,都是识别正确的,这些0的下一个位置,都是人类。即0 next = Human

其次,对于11..1串,从右到左,它们可以这样设置(H代表人类,B代表机器):

0 1 1 1 1 1
H B H B H B

11..1串最后一个字符,也就是从右到左的第一个字符,必定是B,因为它识别错了,下一个位置应该是人类,因为有前提:0 next = Human,而只有机器人才会识别错误。然后逐渐交替,即B H B H B … …。

实际做题的时候,大概感受一下输入样例是怎么得到输出的,然后直接下手写了。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long longconst LL mod_1=1e9+7;
const LL mod_2=998244353;const double eps_1=1e-5;
const double eps_2=1e-10;const int maxn=2e5+10;string str;int main()
{int T, n, i, result, cnt;cin>>T;while (T--){cin>>n>>str;result = 0;n--;for (i=0; i<n; i++){cnt = 0;while (i<n && str[i]=='1'){i++;cnt++;}result += (cnt+1)/2;}cout << result << endl;}return 0;
}

B

看榜单,这么多人做对,而且时间比较短,猜测是比较短代码的题目。

我是稍微想了B没思路,然后先做了C(159分时AC),再折回来做B。那时候时间就很紧张,剩下20分钟。

然后静下心,把这个代码写了。还遇到1e6写成1e5的问题,还有多组测试样例数组的问题。反正我就猜测有什么问题,毕竟是最后1分钟,把有可能发生错误的都试着改一下然后提交,甚至i-K也试着改成i-K-1i-K+1提交一下。运气好,AC了。同时,感觉最近很多场线上比赛压轴提交代码AC,很爽!

因为是\(10^{6}\)复杂度,所以可以处理的算法不多,我想过的有DP,ST算法,感觉时间、空间都挺超的,还有尺取法,等等。我一开始想的,就是贪心,然后逐渐演化而成。

相邻的两个k倍数段(第k * j个段和第k * (j + 1)个段),至少要间隔k个数,然后贪心不了。后来想了一下,哦哦,其实对于某个数(位置为P)作为第k * (j + 1)个段的开头,它就可以以位置1 ~ P-K的任意一个数作为第k * j个段的结尾。记录位置为1 ~ P作为第k * j个段的结尾时的前缀权值之和,然后取它们的最大值:\(\max_{i=1}^{P}(PreSum_{i})\)。每次P位置+1时可以O(1)处理。注意哈,我说的前缀权值PreSum不是前缀和,而是k倍数段中的数的数值之和。

对于第k * j个段,若当前P位置处于这个段,那么P+1位置可以选择添加\(a_{P + 1}\)这个数字,同时这个数仍然处于第k * j个段,仍然可以继续拓展

关键代码:

            start[i] = a[i];value = max(value, start[i-K]);start[i] = max(start[i], start[i-1] + a[i]);start[i] = max(start[i], value + a[i]);

代码细节:

  • \(10^{6}\)
  • 数组每次的初始化(不然WA)
  • K=1无法分割段时的特殊处理(赛后再次测试得知,它是要单独处理的,否则WA)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long longconst LL mod_1=1e9+7;
const LL mod_2=998244353;const double eps_1=1e-5;
const double eps_2=1e-10;const int maxn=1e6+10;LL a[maxn], start[maxn];int main()
{LL T,n,K, sum, i, value;memset(start, 0, sizeof(start));scanf("%lld", &T);while (T--){scanf("%lld%lld", &n, &K);for (i=1;i<=n;i++)scanf("%lld", &a[i]);for (i=1;i<=n;i++)start[i] = 0;value = 0;for (i=1;i<=n;i++){if (i<K)continue;start[i] = a[i];value = max(value, start[i-K]);start[i] = max(start[i], start[i-1] + a[i]);start[i] = max(start[i], value + a[i]);//start[1]~start[i-K]}if (K==1){sum = 0;for (i=1;i<=n;i++)sum += a[i];printf("%lld\n", sum);continue;}sum = 0;for (i=K;i<=n;i++)sum = max(sum, start[i]);printf("%lld\n", sum);}return 0;
}

C

看到这道题,我感受到了可能和这道题有点像,2018 “百度之星”程序设计大赛 - 初赛(A)度度熊学队列,我那时的解法,这道题用list数据结构,把编号为 v 的队列接在编号为 u 的队列的最后面,可以做到O(1)。实际上这道题的数据结构不适用这道题哈。

\(p_{k}\)的数值,只考虑\(k\)这个位置的变化,那么就要从后往前看。比如1->3->2->4,1这个位置,从后往前看(反过来看),swap(1,3)swap(3,2)swap(2,4),最后是一开始的a[4]的数值在1这个位置。感觉遇到过这种这类的题不少次。

然后问题来了,swap(X,Y),就是当前处于X的数处于Y的数交换位置。一个集合和一个集合交换位置,我想到的是像setlistvector这类的数据结构,都可以做到O(1)处理。

然后,就是记录和获取work(L,R,K)的数值。

实际上可能有很多个操作都在同一个位置,但是统一处理降低了复杂度。否则,比如位置1的数值经历了m次修改,n个询问都是问这个位置1,复杂度就是\(O(n*m)\)了。

同时,有些数据结构,无法获取R->L,当到达位置L时,要获取结果然后结束(处理刚好完成后,从某个数据结构中删除)。所以,选择的数据结构需要有排序 / Top的功能。

实际操作中:

  • set,记录(L, Qth)Qth是第Qth个查询。L就是题目中的L(L,R) rangeL
  • vector,记录反过来(从大到小),作为开始的R,有哪些(L,R)对是从某个特定的R开始的。R就是题目中的R(L,R) rangeRR从大从小遍历。
  • R从大从小遍历,处理这个特定的R的若干序列(K,L,Qth)(L,Qth)加入set[K]中。
  • 你并不知道对于特定的(L,R,K),当L处理完后,它在哪个set中。因为setn个(\(n \leq 10^6\)),你总不能依次遍历nset吧寻找吧。一个巧妙的处理点,对于已经在处理第I个操作,在swap(set[ a[i] ], set[ b[i] ])之前,对于第a[i]b[i]set,可以把之前已经处理完的对 删除(erase)了。具体就看哪些对的L值大于现在的I。因为set是自动排序的数据结构,所以这些要处理的(L,Qth)实际上就在set的最后面几个。

代码实际上不长哈,就是有点耗脑

因为很久没写set这类reverse的代码了,写起来很难受,这个地方卡了很长时间。删除一个元素的时候,指针也会发生变化。比如rbegin,erase(it),++it,等等,反正就是很容易写错。这是用文心一言(ChatGPT更好哈)跑"set删除一个元素,它的next指针发生变化"生成的结果。你需要先记录next指针,再删除哈,或者每次删除最大的元素并循环。我写成it = --st[j].end(),让我有点难崩,应该有其它的写法吧,也可以用auto

在 C++ 的 std::set 容器中,元素的存储和访问方式与链表(如单链表或双链表)有很大的不同。std::set 是一种基于红黑树(一种自平衡二叉查找树)实现的关联容器。因此,std::set 中的元素不是通过指针链接在一起的,而是通过节点在红黑树中的位置关系来组织。当你从 std::set 中删除一个元素时,以下几点需要注意:元素指针的变化:在 std::set 中,你通常不会直接操作元素的指针(如 next 指针),因为 std::set 的内部实现是基于节点的,而这些节点之间的链接(父节点、左子节点、右子节点)是由红黑树的性质来维护的。红黑树的调整:当你删除一个元素时,红黑树需要进行一系列旋转和重新着色操作,以保持其平衡性和查找效率。这些操作会改变树的结构,但你不会直接看到或操作这些“指针”(即节点之间的链接)。

调试的时候,不知道为什么,我的VSCode一直爆炸,每次调试后,都得关闭重新打开。我怀疑是set的问题。就像,之前CodeBlocks跑什么发生错误后(比如段错误),这个软件就得出点奇怪的问题,需要重新关闭打开才能调教好。太难受啦!我是第一个遇到这个问题哈,我用VSCode也是因为它的代码自动补全(这场基本没有看到)和CPH插件(也没太多用到,但稍微有点用)。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long longconst LL mod_1=1e9+7;
const LL mod_2=998244353;const double eps_1=1e-5;
const double eps_2=1e-10;const int maxn=1e6+10;typedef pair<int, pair<int, int> > par;
vector<par> vec[maxn];
set<pair<int, int> > st[maxn];
set<pair<int, int> >::iterator it;int result[maxn], a[maxn], b[maxn];
int n, m, q, L, R, K, x, y, z, i;void handle(int j)
{if (st[j].empty())return;while (!st[j].empty()){it = --st[j].end();if (it->first > i){result[it->second] = j;st[j].erase(it);}elsereturn;}
}int main()
{cin>>n>>m>>q;for (i=1;i<=m;i++)scanf("%d%d", &a[i], &b[i]);for (i=1;i<=q;i++){scanf("%d%d%d", &L, &R, &K);vec[R].push_back(make_pair(K,make_pair(L, i)));}for (i=m;i>=1;i--)  //L/R range{for (int j : {a[i], b[i]})handle(j);for (auto temp : vec[i]){x = temp.first;y = temp.second.first;z = temp.second.second;st[x].insert(make_pair(y, z));  //L i}swap(st[ a[i] ], st[ b[i] ]);}i = 0;for (int j = 1; j<=n; j++)  // value rangehandle(j);for (i=1;i<=q;i++)printf("%d\n", result[i]);return 0;
}

P.S. 我觉得好的题的定义

我感觉这种很考思维逻辑,数据结构的题(我指的是前3题,后面没看),ChatGPT很难生成正确的答案。其实AtCoder、CodeForces估计一直有这方面的尝试和讨论,出点很有创新的题目,而不是模板题。有一次我看到AtCoder歪榜,你懂的字数字数

我的个人感悟巴拉巴拉

实力尚还在吧,多年后,一些数据结构有新的感悟,但是一些STL函数使用的确生疏了,写得也相对比较慢,但是代码错误基本会比较少。虽然一开始有点事,后面环境也不是太安静,但是他们都努力降低声音了,set也很久没写了很生疏,但是最后20分钟赶上了第三题的ac,最后两分钟赶上了第二题的ac。看了一下榜,三题AC倒3,这很正常,因为我大大高估了自己做第三题的时间(STL字数字数,太耗时了),第二题最后做的,罚时超大,而且想到的都交了,于是5WA。前100名,187分钟的罚时,大概理想就是10(15) 30 (40) 90(120)吧,实际上挺难的,你还要考虑WA的次数。距离拿衣服还有很远的地步,但是足够了,很开心。话说,拿衣服就不能放宽到200名吗??!!!让兄弟们混件衣服呗!!!感觉参加这次比赛的同学都挺有水平,看它们牛客Ranking和颜色就知道了,普遍ACM银金水平吧。我很多牛客比赛都是乱作的,还有人很菜,然后蓝色,嗯?黑人问号?尊贵的蓝色?嗯???

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【2024.11.05】所谓照片,不过是在时间长河里刻舟求剑罢了

玩摄影一年了,随便瞎写点感受好了 作为模特的感受 想成为一位摄影前就要先练习成为一位模特,这是很有必要的 我觉得九成以上的人难以做到面对镜头时表里如一 在镜头前多少都会紧张,显得不自然 除非是像我一样持续记录自我,已经适应了镜头的存在 而对于模特来说最好的照片是…

Alpha迭代阶段——第七周Scrum Meeting记录

1.Alpha阶段工作内容: 目前是项目调研、设计和游戏系统开发阶段,后续是游戏组件开发阶段。 主要工作为: (1)分析上周Scrum Meeting会议中的不足,总结本周的工作内容和不足,构思下一步的工作内容; (2)探讨游戏关卡的合理性,初步完成游戏关卡设计; (3)初步完成游戏…

19. 使用MySQL之插入数据

1. 数据插入 顾名思义,INSERT是用来插入(或添加)行到数据库表的。插入可以用几种方式使用:插入完整的行;插入行的一部分;插入多行;插入某些查询的结果。补充: 插入及系统安全: 可针对每个表或每个用户,利用MySQL的安全机制禁止使用INSERT语句,这将在第28章介绍 2. 插…

看懂 UML 类图

原文:看懂 UML 类图和时序图从一个示例开始 请看以下这个类图,类之间的关系是我们需要关注的:车的类图结构为<<abstract>>,表示车是一个抽象类; 它有两个继承类:小汽车和自行车;它们之间的关系为实现关系,使用带空心箭头的虚线表示; 小汽车为与 SUV 之间也…

linux 中awk命令实现按照 指定的字符对文本进行排序

001、[root@PC1 test1]# ls a.txt [root@PC1 test1]# cat a.txt ## 测试数据,对如下文本按照a、b进行排序输出 01 02b 03 04 05 06a 07 08 09 10b 11 12 13 14b 15 16 17 18a 19 20 [root@PC1 …

游戏关卡设计文档

关卡设计 关卡一:基础逻辑门练习 任务描述:在这个关卡中,学习如何使用基本的逻辑门(AND门和NOT门)来构建一个简单的“非与”逻辑门。 任务过程:理解逻辑门: 学习AND门的工作原理:只有当所有输入都为高电平时,输出才为高电平。 学习NOT门的工作原理:输出总是输入的…

【入门笔记】CSE 365 - Fall 2024之Computing 101(pwn.college)

真不会了,GDB把我榨干了,会了会回来填坑的【入门笔记】CSE 365 - Fall 2024之Computing 101(pwn.college) Your First Program 你的第一个程序 Your First Register 你的第一个寄存器 CPU的思维方式非常简单。 它移动数据,更改数据,基于数据做出决策,并基于数据采取行动…

Jenkins之代理节点搭建-随笔

背景: 最近在公司搭建Jenkins的CICD,Linux的代理节点,公司前辈已经搭建好了。这次由于需要一个Windows环境作为代理节点,执行UI自动化测试。 于是,就参考了教程搭建完了,花了一个小时吧,最近无聊,就在此简单写一下心得和感受,总体上很简单,遇到了一个坑,但是这个坑…

[SUCTF 2019]CheckIn

题目链接:[SUCTF 2019]CheckIn。 打开后,环境如下。可以看到,是一道文件上传题目,尝试上传 php 文件,发现存在检测。爆破其他可支持的 php 文件后缀无果。 尝试上传 .htaccess 文件,发现存在检测是否为图片的机制。通过加入 GIF 文件幻数后成功绕过检测图片的机制,但是这…

LIS系统与仪器进行通信

本文主要介绍医疗检测仪器与LIS系统之间的通信,两者之间的通信还是比较简单的,两者通过通信方式连接成功后,对接收到的数据按照特定的协议进行解析,拿到我们需要的数据保存到LIS系统,或者将LIS中的数据传到仪器上即可。 下面介绍一下比较常用的通信方式及协议。详细的协议…

0-1搭建 账务自动化集成系统

对财务人员来说,记账是一项非常繁琐又麻烦的工作,每天/月重复,要求还高;如果能实现自动化入账,绝对能提高不少工作效率。这篇文章,我们就来讨论下这个问题。在企业的财务管理中,会计工作是核心环节,会计是基于经济业务活动的根据会计法、会计准则等法律法规,通过记账、…

清结算中台系统设计

在当今复杂的金融交易环境中,清结算中台作为核心的基础设施,扮演着至关重要的角色。它不仅能够确保交易的准确性、安全性和及时性,还能提高金融机构的运营效率,降低风险。 本文将深入探讨清结算中台的定义、流程、模型以及产品功能,为读者全面展示这一重要金融工具的设计与…