P10370「LAOI-4」Mex Tower (Hard ver.)

T3「LAOI-4」Mex Tower (Hard ver.)

Solution:猜性质

打表观察(真的是)得:

  1. 对于 \(n\) 为奇数时:
    1. 中间项必为 2。
    2. 中间项左右两侧必为 \([1,0]\)\([2,0]\)\([0,1]\)\([0,2]\)
  2. 对于 \(n\) 为偶数时,中间两项为 \([0,1]\)\([1,0]\)

细节

  1. 原始数组先处理一遍成只有 \(0,1,2\) 的数组。
  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;
}

posted @ 2024-05-29 21:48  Mr_Azz  阅读(11)  评论(0编辑  收藏  举报