P10370「LAOI-4」Mex Tower (Hard ver.)
T3「LAOI-4」Mex Tower (Hard ver.)
Solution:猜性质
打表观察(真的是)得:
- 对于 \(n\) 为奇数时:
- 中间项必为 2。
- 中间项左右两侧必为 \([1,0]\) 或 \([2,0]\) 或 \([0,1]\) 或 \([0,2]\)。
- 对于 \(n\) 为偶数时,中间两项为 \([0,1]\) 或 \([1,0]\)。
细节
- 原始数组先处理一遍成只有 \(0,1,2\) 的数组。
- \(n\) 为奇数时,特判 \(n=1\) 时情况,此时只需要 \(a_1=2\) 即可。
证明:
其实在手模的时候就可以看出不超过 4 次操作后,继续操作两次相当于减去一对头尾,最后剩下的只有中间。所以中间只要构造为 \([0,2,1]\) 或者 \([0,1]\) 这样的样子。
Code:
signed main(){
read(T);
while(T--){
read(n);
for(rint i=1;i<=n;i++) read(a[i]);
n--;
for(rint i=1;i<=n;i++){
if(a[i]!=0&&a[i+1]!=0) a[i]=0;
else if(a[i]!=1&&a[i+1]!=1) a[i]=1;
else a[i]=2;
}//细节1
bool f=0;
if(n%2==1){
int t=(n+1)/2;
if(t==1&&a[t]==2) f=1;//细节2
else if(a[t]==2&&a[t-1]!=a[t+1]&&(a[t-1]==0||a[t+1]==0)) f=1;
}
else{
if(a[n/2]+a[n/2+1]==1) f=1;
}
puts(f?"Yes":"No");
}
return 0;
}
打表代码:
int n;
inline int work(vector<int> a){
for(rint k=1;k<a.size();k++){
for(rint i=1;i<a.size();i++){
if(a[i-1]!=0&&a[i]!=0) a[i-1]=0;
else if(a[i-1]!=1&&a[i]!=1) a[i-1]=1;
else a[i-1]=2;
}
}
return a[0];
}
inline void dfs(int p,vector<int> a){
if(p>n){
if(work(a)==2){for(auto x:a) cout<<x<<" ";puts("");}
return ;
}
a.push_back(0);
dfs(p+1,a);
a.pop_back();a.push_back(1);
dfs(p+1,a);
a.pop_back();a.push_back(2);
dfs(p+1,a);
return ;
}
signed main(){
cin>>n;
dfs(1,{});
return 0;
}