Back to blog
Sep 09, 2026
1 min read

Codeforces Round 1119 (Div.3) Recap

考验思维和手速……

这场出现了不少字符串变量。但也只是出现变量而已,并不涉及什么字符串处理和算法)

A

(又卡在了 s[i]=='0' 和 s[i]=0 ……╮( ̄▽ ̄"")╭ 卡了五分钟没反应过来

B

在执行次数上去之后,奇数会变成1,偶数在0和2之间反复横跳。判断一下奇数和两组同相偶数哪一组数量最多就行。

C

贪心。正反向分别搜索,跳过0,若首次出现的是-1而不是1,将-1改为1;中间的所有-1改为0。

因为(去0后的)头和尾的-1改为1并不会导致 max(k) 变小。

D

控制好 0 的分布,就能轻松控制MEX的分布。

对于 $MEX(𝐴)+MEX(𝐵)+MEX(𝐶)≥2⋅max(MEX(𝐴),MEX(𝐵),MEX(𝐶))$ ,不妨设三者的 MEX 从小到大排序后分别为 x≤y≤z(其中 z=max)。 不等式即为:$x+y+z≥2z⟺x+y≥z$ 。 这个不等式本质上就是 “较小的两数之和不小于最大数”(类似于退化的三角形不等式)。 若要让它不成立,唯一情况是较小的两个值太小,撑不起最大的那个值(即 $x+y<z$)。

由于集合里若没有元素0则mex=0,则可以从0的个数入手去做分配。

对于整个序列中 0 的出现次数 c:

  1. c=0:全员没有 0,三个集合的 MEX 都是 0,满足 0+0≥0,直接随便分。
  2. c=1:唯一的 0 只能落入一个集合中,其余两集合的 MEX 必为 0,而包含 0 的集合 MEX≥1,导致较小两数之和为 0<z,恒不成立,输出 NO。
  3. c≥2:我们只需构造使得 MEX 分别为 1,1,0。将一个 0 给 A,剩余的 0 给 B,所有非 0 元素全部扔给 C。此时 MEX(A)=1,MEX(B)=1,MEX(C)=0,满足 0+1≥1,直接输出该方案即可。

代码:

void solve() {
    int n,c=0;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if(a[i]==0) c+=1;
    }
    if(c>=2){
        cout<<"YES\n";
        int cnt=0;
        for (int i = 0; i < n; i++){
            if(a[i]==0 && cnt==0) {cout<<"A"; cnt+=1;}
            else if(a[i]==0) cout<<"B";
            else cout<<"C";
        } //构造出来是{0,1,1},必定满足条件
        cout<<"\n";
    }
    else if(c==1){
        cout<<"NO\n";
    }else{
        cout<<"YES\n";
        cout<<"ABC"; //题目限制n>=3,所以能这么写
        for (int i = 3; i < n; i++) cout<<"A";
        cout<<"\n";
    }
}

(ps. 我一开始居然直接sort了a(n)之后再去处理数据……角标位置都完全变了。又在这里卡了快十分钟

E

(暂略)

F

冒泡排序的特点:每次冒泡必将最大(最小)的数移到末尾。

(这题喜提两发惩罚……第一发爆int,第二发数组越界RE…………

G

H

(暂略)