总述:这次比赛第一题纯数学题,后三题以模拟为主,每道题都能做,但是想要最对很难。第一题完全正确,主要讲解第2~4题,以 下为每道题的分析:
第一题:
链接:2021CSP-J2-T1
主要思路:此题答案最大为n-1,用循环一一枚举必定超时,二分没有单调性,所以要采用数学的算法.
情况1:当l和r刚好差一轮时答案必定是n-1
情况2:不符合上述情况最优取r,所以答案为r%n
主要代码见下方
if(r/n-l/n)cout<<n-1<<endl;
else cout<<r%n<<endl;
第二题:
链接:2021CSP-J2-T2
主要思路:
n个元素的上一数组a和最新数组b,q次操作:
操作种类如下 :
1、 (1)输入操作类型1,下标x,和数值v
(2)b[i] = a[i] ||1<=i<=n //更新数组
(3)b[x] = v; //进行修改操作
(4)按升序重排b[n] 1)
(5)把a[i]所在b数组中的位置放入w[i] || 1<=i<=n 2)
(6)a[i] = b[i] || 1<=i<=n]
2、 (1)输入操作类型2,下标y
(2)输出w[y](及a[y]在b数组中的位置)
具体细化:
1) 此题n最大为8000,每经过一次操作1就要进行1次排序,题目已说明操作1最多有5000次。
(1)冒泡排序:O(50008000^2)=O(32e10)爆超肯定不用
(2)快速排序:O(50008000log2(8000))算一下O(5.2e8)大概用5秒也超时
(3)最优解:修改的数与其他数一一比较交换,时间复杂度O(n)
2)在将上一数组下标统计中,用O(n^2)或O(nlog2(n))统计均为超时如上
最优采取数组元素值数组统计,时间复杂度为O(n)肯定满足,但空间上就不行了。所以要离散化来处理。
没做出来原因经验:(1)没有将题目拆解分别思考。
(2)在思考时应当实现在纸上,思考不一定全面。
第三题:
链接:2021CSP-J2-T3
主要思路:此题纯模拟,主要考查代码能力。
给出n个计算机类型,和型号,输出每台的状态情况。
计算机类型如下:
标准: a.b.c.d:e (0<=a,b,c,d<=255)(0<=e<=65535)
1.Server 服务机
if(非标准)ERR
else if(与之前服务机重复)FAIL;
else OK,记录;
2. Client 客户机
if(非标准)ERR;
else if(之前没有与其型号相同的服务机)FAIL;
else 之前服务机与其型号相同所对应的编号;
难点:如何判断是否标准型号**(准确,没有漏洞)**
代码实现如下:
int x[10]//用来保存从字符串中提取出来的数
string a;
bool is_good(string a){
int cnt=1,len=a.length();
for(int i=0;i<len;i++){ //遍历字符串
if(a[i]>='0'&&a[i]<='9'){ //是数字字符
if(x[cnt]==0&&a[i]=='0')return false;//前缀0判断
x[cnt]=x[cnt]*10+a[i]-'0'; //向前合并
}
else { //是其他字符
if(cnt>=1&&cnt<=3){
if(a[i]!='.')return false;//'.'判断
}
else if(cnt==4)if(a[i]!=':')return false;//':'判断
}
}
if(cnt>5)return false;//最终数量判断
return true;
}
没做出来原因经验:(1)题目比较复杂,需要静下心用笔写出框架。
(2)(平常)在平时写代码要不断优化自己的代码,这样才能保证在比赛中将代码写的最简单最准确
第四题:
链接:2021CSP-J2-T4
主要思路:给出n个数字0或1,相同数字相邻在一起形成堆,每次输出每堆最左边的数字的下标,并删除,直至没有数字为止。
主要采用方法链表:
1.链表初始化
2.当还有元素存在时while循环
(1)模拟还存在的元素while循环
(1)(1) if(和上一元素不同)
(1)(1)(1)更新链式关系
(1)(1)(2)删除元素
(1)(1)(3)总元素数量–;
(1)(1)(4)输出下标
(1)(2)下标更新
(2)寻找新的起点
(3)输出换行符
分块维护:
1.每堆为一数组里的元素
2.但是当有堆被彻底删完时,合并是个问题(暂时没有思考出来)
没做出来原因及经验:对链表数据结构不太熟悉,反映出要多写复习算法及数据结构的代码
总结:(1)发挥失常:没有将想法细化处理
(2)复习:要多写一些算法数据结构的代码
(3)思考:用纸质表现