标签:就是 using oid code namespace sizeof mes out tor
先对数组升序排序。
排序后,顺次枚举数组中的每个数。
令两个子集分别为 \(A\) 与 \(B\), 读入数组为 \(q\).
对于每个 \(q[i]\):
若 \((q[i]-1)\notin A\)(即此数的前驱不在 \(A\) 中,换句话说就是 \(\operatorname{mex}(A)=q[i]-1\)) 或 \(q[i]\in A\)(即此数在 \(A\) 中已经存在), 则表示如果将 \(q[i]\) 放入 \(A\) 集合中并不能使 \(\operatorname{mex}(A)\) 增加,故唯有将其放入 \(B\) 集合中才有可能增加答案;
反之,则将其放入 \(A\) 集合中。
枚举完后再遍历一下两个集合,求出答案即可。
需要注意的是,在实现上,因为笔者使用桶维护两个集合,所以在判断 \(q[i]-1\) 是否在桶中时可能会使数组下标为 \(0-1=-1\). 所以笔者在读入时便将每个 \(q[i]\) 都自加 \(1\), 以避免这种情况。但是在统计答案时注意要减一下(还要注意一下 \(\operatorname{mex}\) 比值域大的情况,这里不再赘述)。事实上,用 std::set
啥事没有。
By the way, 这种做法其实还比较麻烦,有更简单的思路。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
const int Size=102;
int n;
int q[maxn];
bool A[Size],B[Size];
int mex(bool A[]){
for(int i=1;i<Size;i++){
if(!A[i]){return i-1;}
}
return 101;
}
void work(){
memset(A,false,sizeof A);
memset(B,false,sizeof B);
A[0]=B[0]=true;
cin>>n;
for(int i=0;i<n;i++){
cin>>q[i];
q[i]++;
}
sort(q,q+n);
for(int i=0;i<n;i++){
if(!A[q[i]-1]||A[q[i]]){
B[q[i]]=true;
}else{
A[q[i]]=true;
}
}
cout<<mex(A)+mex(B)<<endl;
}
int main(){
int T;cin>>T;
while(T--){work();}
}
标签:就是 using oid code namespace sizeof mes out tor
原文地址:https://www.cnblogs.com/Xray-luogu/p/14362058.html