CSP-J复赛模拟补题报告
2023.10.4星期three
1.比赛分数
T1(digit):20
T2(skill):60
T3(equal):0
T4(variance):0
2.比赛过程
T1一开始认为时间肯定会爆,所以想用空间换时间,为了把时复压到On(100000级别),开了个2维数组。结果后面一算要么越界要么爆MLE所以最后就把数组从1000000000级别缩小到10000000,越界了。赛后一看思路貌似比题解更好一点,但是没用map优化所以爆了。(题解也会爆时间不过测试点很仁慈)
T2做的时候只剩1个小时了,浅浅暴力打了一下就没有想太多,少了2种特殊情况的讨论。
T3一开始以为是固定一个点然后往另一个方向找,后面发现他这个和子串一样不能分开,所以就当骗分了(主要没时间)。
T4不知道什么是方差,也没有旁边这位兄弟的孕气,所以爆0了。
3.题解报告
1.数字对应digit
(1)情况:赛中20,已补题
(2)题意
咳咳,我真腻害
(3)题解
第一眼看到这个数据应该都会懵一下。对于基本思路要求n*Ai也就是10的14次方的时复。这里肯定要优化的。这里是的优化思路:
#include<iostream>
#include<cstdio>
using namespace std;
long long m[10005][1005],a[100005],a1[100005]={0},a2[100005];
long long n,b[100005],sum=1;
int main(){
freopen("digit.in","r",stdin);
freopen("digit.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
a1[i]=a[i];
a2[i]=a[i];
b[a[i]]++;
m[a[i]][b[a[i]]]=i;
}
for(int i=1;i<=(n+n+2);i++){
if(a1[sum]==-114514){
while(a1[sum]==-114514){
sum++;
}
}
if(b[i]==0&&a1[sum]!=-114514){
for(int j=1;j<=b[a[sum]];j++){
a1[m[a[sum]][j]]=-114514;
a2[m[a[sum]][j]]=i;
}
sum++;
}
}
for(int i=1;i<=n;i++){
cout<<a2[i]<<" ";
}
return 0;
}
不过这个肯定是MLE的,所以需要用到map优化:
但是我没学过map,所以。。。
其实仔细看看这个题解就可以发现他最差情况应该时复为10000000000,会爆的,但测试点很仁慈啊。
2.技能学习skill
(1)情况:赛中60,已补题
(2)题意
(3)题解
这个题肯定要降到常数复杂度,直接分4种情况:
1.不够直接输出0
2.不够全k
3.够全k
4.超
分情况讨论就OK,下面时AC码
3.等于equal
(1)情况:0
(2)题意
(3)题解
由于只有-2,-1,1,2四个数字,所以可以直接分情况讨论:
第一种情况:区间中只有同一种数字。这个比较简单,通过简单的 for 循环向后计数得到。
第二种情况:区间中最大值和最小值为相反数,就是最大值 ,最小值 ,和最大值 ,最小值 。
在这里浅浅复述下这段代码的意思。
首先将初始化nxt数组都为0x3f方便后面计算。
开始算第一种情况,当一样时继续加ret,不一样的话就结算下并初始化ret=1(最后一个没加上去就else了)。因为最后一组也没有else所以要再写一次。
然后就是第二种情况,先把所有的都遍历一遍并复值,然后找他的i右侧最左侧-2设为start和最右侧的设为end,找end右边和start与end间区间的情况,然后算-1的。最后输出总情况就OK了
(4)第四题我没搞明白!!!
4.比赛总结
不会不会还是不会,只能说还是太蒟蒻了。