2026 CCF CAT 反思——于诗涵

2026 CCF CAT 2026反思——于诗涵

题目数量:10      AC数量:5

这次的比赛成绩,虽然有一些不满意,但相比于去年还是有一定的提升,去年如果没有组队我大概只能打 \(3\) 道题,今年多了 \(2\) 道,也可能是今年的前三题比较简单。

A B C

这三道题非常简单,没什么需要总结的。

D

\(D\) 这道题是我这次比赛最失败的一道题,\(wa\)\(6\) 次,最开始有些着急,想快点写让罚时少一点,思路想的很快,也是对的,写完测了一下样例就交了,因为答案有多种可能没有细看输出对不对就交了,后来发现样例都没对,只得了 \(5\) 分,调了一会交了几遍后 \(90\) 分了。

但是就是不知道错哪了,还写了一个验证程序,数据范围 \(\le 1e7\) 都没有问题,又交了两次还是 \(90\),当时心态就不是很好了,看榜发现我的速度垫底了,很着急,想跳过这道题,但感觉 \(90\) 分没差多少了,而且这个赛制没有部分分,\(90=0\)

后来实在调不出来了,打算放弃了,改了个认为没问题的地方交了一下,结果过了,原因是求二进制位数的时候是这样写的

$int$   $len=(int)ceil(log2(y+1));$

被卡了,因为之前很多题都这么写,也没有问题就没怀疑这块,结束后查了一下,发现当 \(y\) 很大时,精度会有误差。

如果是 \(OI\) 赛制,样例比较多,也不着急罚时,肯定不会出现 \(5pts\) 的情况,但剩下的 \(10pts\) 肯定也得不到。

总结:

  • 要养成好的代码习惯,尽量不要写这种怪异不常见的写法,比赛时容易被卡。
  • 心态要好,做不出来时千万不要着急,否则思路会更混乱。

E

\(E\) 的过程非常顺利,做题节奏也很好。因为刚过了 \(D\),心情很放松,读题、思考、写代码加起来用了 \(20min\)\(E\) 就过了。简单来说只需要求一下前缀 \(max\) 和后缀 \(min\),就可以 \(A\) 掉这道题。

F

\(F\) 是一道很可惜的题,写完 \(E\) 还有一个半小时多,\(F\) 交了几次,几乎都是 \(64pts\) ,我想的做法是贪心,\(DP\) 也可以写这道题,但我没有想到,我的贪心在思路上有一些问题,考虑的两种情况,有一种还可以继续延伸。

刚开始没有找到 \(hack\),结束前 \(6min\) 时,找到了一组 \(hack\),但没有调完,赛后调了一个多小时,调出来了。

我贪心的思路比较冷门,暂时还没有找到和我一样思路的人,而且代码也不是很好写,有很多细节。

附赠代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
char s[N];
int a[N],b[N];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,cnt=0,len=0;
        scanf("%d",&n);
        scanf("%s",s+1);
        b[++len]=0;
        for(int i=1;i<=n;i++){
            if(s[i]=='R') a[i]=1;
            if(s[i]=='G') a[i]=2;
            if(s[i]=='B') a[i]=3;
            if(s[i]=='N'){
            	a[i]=0;
            	b[++len]=i;
			}
        }
        b[++len]=n+1;
        a[n+1]=0;
        for(int k=1;k<len;k++){
        	for(int i=b[k]+1;i<=b[k+1]-1;i++){
	            if(a[i]==0) continue;
	            int j1=i;
	            while(a[j1]==a[j1+1]&&j1<b[k+1]-1) j1++;
	            cnt++;
	            if(j1==b[k+1]-1) break;
	            int j2=j1+1;
	            int e=a[j2];
	            if(a[j2]==0){
	                i=j2;
	                continue;
	            }
	            a[j2]=6-a[j1]-a[j2];
	            while(e==a[j2+1]&&j2<b[k+1]-1){
	                j2++;
	                a[j2]=6-a[j1]-a[j2];
	            }
	            if(j2==b[k+1]-1){
	                cnt++;
	                break;
	            }
	            if(a[j2+1]==a[j1]){
	                int c=0,flag=0;
	                int j3=j2+1,j4;
	                while(a[j3]==a[j1]){
	                    while(a[j3]==a[j3+1]&&j3<b[k+1]-1) j3++;
	                    if(j3==b[k+1]-1){
	                        break;
	                    }
	                    c++;
	                    j4=j3+1;
	                    while(a[j4]==a[j3+1]&&j3<b[k+1]-1) j3++;
	                    j3++;
	                }
	                cnt+=c;
	                for(int l=j4;l<j3;l++) a[l]=6-a[j1]-a[l];
	                if(j3>=b[k+1]-1){
                        cnt++;
                        break;
                    }
	                i=j4-1;
	            }
	            else i=j1;
	        }
		}
        printf("%d\n",cnt);
    }
    return 0;
}

总结

  • 可以提升一下找 \(hack\) 的能力。
  • 不要轻易放弃,不要总是觉得思路是错的。

H

赛时还看了一下 \(H\),感觉 \(H\)\(G\) 简单,尝试写了一下,写完后发现有问题,这个代码不对,但是如果改的话就会超时,于是果断放弃了 \(H\)

但感觉如果时间再多一点H应该是有希望能写出来的。

总结

  • 要想好再写,不要写完代码发现不对,会浪费时间。
posted @ 2026-06-18 23:35  yushihan  阅读(20)  评论(0)    收藏  举报