CCF csp-J/S 2025游记

· · 生活·游记

初赛:

考试前几天做了浩谷的SCP和有道的模拟比赛,都在40多分,成绩不是很理想,但想想身在弱省,去年第一轮模拟分数不超过20分的我照样能过初赛便又有了信心(不会有人初赛没过吧~)。

考试当天早早便起床,提前将近一个小时到考点,发现今年又多了一个考场,压力倍增,还有其它机构的老师给他们的学生发吃的,红牛配巧克力!!!一数,今年又少了20个对手。J、S都考完后感觉S貌似比J蒙(用词准确)的更好,S组的"you have no egg"至今记忆犹深(可能是整篇就着懂这个吧)。 成绩出后果然不出所料,轻松愉快的过了初赛,又开始了松散(紧张?不存在的)的复赛备赛之路,备赛时发现了梦熊的-J20连测宣传的挺好的,嗯,1场100元,嗯……虽然做了题发现唯一能着懂题的只有第一题……而且…太难了,所以没做几套……由于太蒟蒻了,算法一点也不会,今年日标只能定在-J一等(弱省是这样的)-S二等了,去年其实-J已经拿到二等了,但……成绩就100分……第一题写了200多行,怎么说呢……不会有比我还差的了吧(小学生应该也知道用for代替我的200行if吧…)

复赛:(-J)

15分钟解决第一题,比去年不知道简单了几百倍,测了一个数据发现有点超空间(主观,无证明),冒险将int改成了short(已知数据中数字不超过9)(但short没用过,只是听说过)。第二题看到后,心里就稳了,超简单,小学数学题排坐,分类讨论就可以了,当然,不要问我为什么分类讨论写了1个小时!!写完后最不保准的就是这题,以神奇的方式通了样例,以至于我检查的时候就看不明白自己写的是个什么了,但能运行就不动它……。第三题我只想到了前缀异或和,其实在这之前花了10分钟研实什么是异或了,最后只写出了O(n²)的代码,但正解虽然也用了前缀异或,但是O(n),遗憾只拿了75分,最后一题一看就知道不是给人写的,直接输出“0”拿了4分,剩了1个小时,检查一下freopen,感谢前桌帮我找到了电脑中的贪吃蛇、俄罗斯方块。(考试前)

最后100+100+75+4=279也很满意了。

(附非零代码以作纪念)(真的不是凑字数!!)

nunber(100)


#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
string a;
short s[1000001]={};
long long sum=0;
cin>>a;
for(int i=0;i<=a.length()-1;i++){
if(a[i]>='0'&&a[i]<='9'){
s[sum]=int(a[i])-48;
sum++;
}
}
sort(s,s+sum);
for(int i=sum-1;i>=0;i--){
cout<<s[i];
}
return 0;
}
> seat(可见毫无逻辑)(100)
```cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
    freopen("seat.in","r",stdin);
    freopen("seat.out","w",stdout);
    int n,m;
    long long r,sum=0,a,hang=0,lie=0,zuo=0;
    cin>>n>>m;
    cin>>r;
    for(int i=2;i<=n*m;i++){
        cin>>a;
        if(a>r){
            sum++;
        }
    }
    sum++;
    lie=sum/n;
    zuo=sum%n;
    if(zuo==0){
        if(lie%2==0){
            hang=1;
        }
        else{
            hang=n;
        }
        cout<<lie<<" "<<hang<<endl;
        return 0;
    }
    lie++;
    if(lie%2==0){
        hang=n-sum%n+1;
    }
    else{
        hang=sum%n;
    }
    cout<<lie<<" "<<hang<<endl;
    return 0;
}

xor(75)


#include<bits/stdc++.h>
using namespace std;

int main(){ freopen("xor.in","r",stdin); freopen("xor.out","w",stdout); int a,s[500002]={},n,k; long long xo=1,sum=0; cin>>n>>k; cin>>a; s[1]=a; for(int i=2;i<=n;i++){ cin>>a; s[i]=s[i-1]^a; } for(int i=1;i<=n;i++){ for(int j=xo;j<=i;j++){ if(j<xo){ continue; } if(i==j&&(s[i]^s[i-1])==k){ xo=i+1; sum++; continue;

        }
        if(j==1&&s[i]==k){
            xo=i+1;
            sum++;
            continue;
        }
        if((s[i]^s[j-1])==k){
            xo=i+1;
            sum++;
            continue;
        }
    }

}
cout<<sum<<endl;
return 0;

}

> polygon(4)
```cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
    freopen("polygon.in","r",stdin);
    freopen("polygon.out","w",stdout);
    cout<<"0"<<endl;
    return 0;
}

中午去吃了顿麻辣烫,美味!!

(-S)

真的是上午有多简单下午就有多难,看到题后只剩麻辣烫的美味了,一点思路也没有,想了一会儿发现第一题貌似可以贪心每个人的最大贡献,然后就到了最难的移动人员问题上了,第一想法是dp,然后……嗯……dp状态转移方程根本写不出来,几手全忘了 (后来想想,多亏没学dp,否则就会在转移方程中一去不复返了),接着就是想怎样跳过dp,想了半个小时,抬头一看,大家好像都没想出来,一个小时后想出了:先贪心最大供献再将第二贡献排序(排序前先求最大贡献与其它贡献之差)的方法,然后证明了仅有一个部门会超人数后,成功写出正解,剩下三道题看到题就绝望了,第二题的图一点没接触过、考场上尽力证明连通性判定,但没证出来,第三题写了个暴力,纯暴力,(考试后听说暴力加KMP能得30分,但纯暴力能得25分己经知足了),剩下就又是俄罗斯方块和贪吃蛇的美好时光。最终成绩:俄罗斯方块1000分,贪吃蛇最长35!(你不会以为我要说-S的成绩吧)。 最后 100+0+25+0=125。

club(100)

#include<bits/stdc++.h>
using namespace std;
struct bu{
int f1;
int f2;
int f3; 
};
int main(){
freopen("club.in","r",stdin);
freopen("club.out","w",stdout);
int T,n,max1=0;
cin>>T;
while(T--){
n=0;max1=0;
cin>>n;
bu a[100001]={};
int q[100001]={},q1=0;
int amax=0,a1=0,a2=0,a3=0;
long long sum=0;
max1=n/2;
for(int i=1;i<=n;i++){
cin>>a[i].f1>>a[i].f2>>a[i].f3;
amax=max(a[i].f1,max(a[i].f2,a[i].f3));
sum+=amax;
a[i].f1-=amax;
if(a[i].f1==0)a1++;
a[i].f2-=amax;
if(a[i].f2==0)a2++;
a[i].f3-=amax;
if(a[i].f3==0)a3++;
}
if(a1<=max1&&a2<=max1&&a3<=max1){
cout<<sum<<endl;
continue;
}
else{
if(a1>max1){
max1=a1-max1;
for(int i=1;i<=n;i++){
if(a[i].f1!=0){
continue;
}
else{
q[q1]=max(a[i].f2,a[i].f3);
q1++;
}
}
}
else if(a2>max1){
max1=a2-max1;
for(int i=1;i<=n;i++){
if(a[i].f2!=0){
continue;
}
else{
q[q1]=max(a[i].f1,a[i].f3);
q1++;
}
}
}
else if(a3>max1){
max1=a3-max1;
for(int i=1;i<=n;i++){
if(a[i].f3!=0){
continue;
}
else{
q[q1]=max(a[i].f2,a[i].f1);
q1++;
}
}
}
}
sort(q,q+q1);
for(int i=q1-1;i>=q1-max1;i--){
sum+=q[i];
}
cout<<sum<<endl;
}
return 0;
}

replace(25)

#include<bits/stdc++.h>
using namespace std;
    int n,q;
    long long sum=0;
    string a[200001]={},a1[200001]={},q1,q1ans;
    bool qwe[200001]={};
int main(){
    freopen("replace.in","r",stdin);
    freopen("replace.out","w",stdout);
    cin>>n>>q;
    for(int i=1;i<=n;i++){
        cin>>a[i]>>a1[i];
        qwe[a[i].length()]=true;
    }
    for(int i=1;i<=q;i++){
        sum=0;
        cin>>q1>>q1ans;
        for(int i=0;i<=q1.length()-1;i++){
            for(int j=0;j<=i;j++){
                if(qwe[i-j+1]==false){
                    continue;
                }
                string q2x,q2y,q2,q2z,q1x,q1z;
                for(int z=0;z<j;z++){
                    q2x+=q1[z];
                    q1x+=q1ans[z];
                }
                if(q1x!=q2x){
                    continue;
                }
                for(int z=i+1;z<=q1.length()-1;z++){
                    q2z+=q1[z];
                    q1z+=q1ans[z];
                }
                if(q1z!=q2z){
                    continue;
                }
                for(int z=j;z<=i;z++){
                    q2y+=q1[z];
                }
                for(int z=1;z<=n;z++){
                    if(qwe[i-j+1]==true&&q2y==a[z]){
                        q2=q2x+a1[z]+q2z;
                        if(q2==q1ans){
                            sum++;
                        }
                    }
                }
            }
        }
            cout<<sum<<endl;
    }
    return 0;
}

最后感谢锡山高级中学(我真的不是这个学校的

以此游记纪念我的最后一次CSP之旅,中考加油!

2025年11月10日

写于不想写作业的夜晚