题目大意:给你一个数组a,有n个元素, 每个元素都是0->n-1里面的一个,可能拥有重复元素,定义mex为0->n中第一个没有出现在a中的数,问,想让这个数mex变成mex+1,能否做到。
思路:
分类:
1.当mex+1没有出现时:
(1)当mex>=n,此时肯定无法构成,因为一旦构成,便会越界。
(2)当mex<n时,肯定能构成,因为如果一个n个数组中的数由0->n-1构成,但是有的数没出现,必然有重复数据,那么我们只需要拿走重复数据中的一个数改成mex即可。
2.当mex+1出现时:
我们只需要找出全部mex+1的整体区间范围,把他变成mex即可,但是这是理想化的,如果在这个区间范围内存在小于mex的数那么,最终我们再求出来的数就肯定不是mex+1,此时就是NO;否则就是YES。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+7;
int t,n;
int a[maxn];
int mex(){
map<int,int> mp;
for(int i=1;i<=n;i++){
mp[a[i]]=1;
}
for(int i=0;i<n;i++){
if(!mp.count(i)){
return i;
}
}
return n;
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int me=mex();
int l=-1,r=n;
for(int i=1;i<=n;i++){
if(a[i]==me+1){
if(l==-1)
l=i;
r=i;
}
}
if(l==-1){
if(me<n)
cout<<"Yes"<<"\n";
else
cout<<"No"<<"\n";
}else{
for(int i=l;i<=r;i++){
a[i]=me;
}
int cur=mex();
if(cur==me+1)
cout<<"Yes"<<"\n";
else
cout<<"No"<<"\n";
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>t;
while(t--){
solve();
}
return 0;
}