这场出现了不少字符串变量。但也只是出现变量而已,并不涉及什么字符串处理和算法)
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:
- c=0:全员没有 0,三个集合的 MEX 都是 0,满足 0+0≥0,直接随便分。
- c=1:唯一的 0 只能落入一个集合中,其余两集合的 MEX 必为 0,而包含 0 的集合 MEX≥1,导致较小两数之和为 0<z,恒不成立,输出
NO。 - 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
(暂略)