想法:本题分为两种情况,一种是mex(a)+1存在于数据中,另一种是mex(a)+1不存在。
对于第一种情况,我们需要将mex(a)+1最先出现到最后出现的一串数据全变为mex(a),之后再次判断改变后的mex(a)是否为原先的mex(a)+1
第二种情况,需要判断数据是否有重复。如果是0123这样的,是不可行的。但若是0 1 2 2 ,那就是可行的。
知识点:set函数的运用,set.find(it), set.insert(a[i])
思考:这是我写的第三道A题,我发现我考虑这种问题特别喜欢把特殊情况拎出来写,久而久之代码里就堆满了if。正确做法应该是用一句话概括做法(把握大方向),这道题我做的时候忽略了最重要的点(mex(a)+1是否存在)。#866div2的A题我也想的太复杂了,其实做法就是一句话“在两个-中间插入^”
易错点:求头尾的时候可以先把头值给尾值,避免只有一个数
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
const int N=2e5+5;
int a[N];
int mex(int n){
set<int>st;//每次重新放入数据
for(int i=0;i<n;i++){
//cout<<a[i]<<endl;
st.insert(a[i]);//放入不重复数据
}
int it=0;
for(it=0;;it++){
if(st.find(it)==st.end()){//如果没有找到就返回end位置
return it;
}
}
}
void solve(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int m=mex(n);
int pre=-1;int next=-1;//初始化!!
bool flag=false;
for(int i=0;i<n;i++){
if(a[i]==m+1&&flag==false){
pre=i;flag=true;next=i;//注意此时next也要变
}
else if(a[i]==m+1&&flag==true){
next=i;
}
}
if(pre==-1){
if(n==m)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
else{
for(int i=pre;i<=next;i++){
a[i]=m;//cout<<a[i]<<endl;
}
int res=mex(n);
if(res==m+1)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
int main()
{
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}