#8816. Solar Panel Grid Optimization 题解

题目链接:#8816. Solar Panel Grid Optimization

先统计最后一行一列的 $ \texttt{1} $ 的数量,如果小于 $ n $ 则把 $ a $ 和 $ b $ 全部反转(显然不影响答案),然后先把最后一列调成全是 $ \texttt{0} $(不断执行 $ \texttt{row(n)} $ 遇到 $ \texttt{0} $ 就执行 $ \texttt{column(n)} $ ),然后再把最后一行调整成全是 $ \texttt{0} $(和列的调整所需操作完全一样),然后执行 $ \texttt{column(n)} $ 总共 $ n $ 次让最后一列全是 $ \texttt{1} $,然后如果当前顶端需要出现一个 $ \texttt{0} $ 则执行 $ \texttt{column(n)} $,否则执行 $ \texttt{row(n) column(n)} $。记 $ q_i=\Big(\bigoplus_{j=1}^n b_{i,j}\Big)\oplus \big((n-1)\bmod 2\big) $ 即这一行目标的异或和,最后的 $ \big((n-1)\bmod 2\big) $ 是因为后面填充前 $ n - 1 $ 列的过程会反转最后一列 $ n - 1 $ 次,$ r_i=\bigoplus_{j=1}^n a_{i,j} $ 即初始异或和,$ d_i=q_i \oplus r_i $ 即最后一列的目标状态,按照上文提到的方法调整即可

对于前 $ n-1 $ 列,第 $ i $ 轮最终填充到第 $ i $ 列,然后先扫一遍所有行,对于 $ a_{j,n} = b_{j,i} $ 的所有行 $ j $ 都执行一次 $ \texttt{row(j)} $,然后执行 $ n $ 次 $ \texttt{column(n)} $ 反转最后一列的状态,再把前面没有执行 $ \texttt{row} $ 的行执行一次。最终因为提前构造的 $ d_i $ 刚好补上了最后一列所以构造成功。

操作次数上界显然小于等于 $ n + n + n + n + 2n^2 = 4n + 2n^2 \le 880 < 1000 $,满足要求。

代码:

#include<bits/stdc++.h>
#define time(null) chrono::steady_clock::now().time_since_epoch().count()
#define int long long
#define uint unsigned long long
#define debug() cout<<"come here\n"
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define pb push_back
#define Code return
#define by 0
#define MCYYDS ;
using namespace std;
int qpow(int a,int b,int p=INF){int ret=1;while(b){if(b&1)ret=(ret*a)%p;a=(a*a)%p;b>>=1;}return ret;}
inline int read(){int ret=0,f=1;char ch=getchar();while(ch<'0'||ch>'9')f=(ch=='-'?-1:f),ch=getchar();while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();return ret*f;}
inline void write(int x){if(x<0){putchar('-');write(-x);return ;}if(x>9)write(x/10);putchar((char)(x%10+48));}
inline void writech(int x,char ch){write(x);putchar(ch);}
int n;
vector<vector<int> > a,b;
vector<pii > ans;
void row(int x)
{
	ans.pb({0,x});
	vector<int> tmp(n);
	for(int i=0;i<n;i++)
	{
		tmp[i]=a[x][(i+1)%n];
	}
	for(int i=0;i<n;i++)
	{
		a[x][i]=tmp[i];
	}
}
void col(int x)
{
	ans.pb({1,x});
	vector<int> tmp(n);
	for(int i=0;i<n;i++)
	{
		tmp[i]=a[(i+n-1)%n][x];
	}
	for(int i=0;i<n;i++)
	{
		a[i][x]=tmp[i];
	}
	a[0][x]^=1;
}

signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);
//	cout.tie(0);
	n=read(); 
	a.resize(n);
	b.resize(n);
	for(int i=0;i<n;i++)
	{
		a[i].resize(n);
		b[i].resize(n);
	}
	for(int i=0;i<n;i++)
	{
		string s;
		cin>>s;
		for(int j=0;j<n;j++)
		{
			a[i][j]=s[j]-'0';
		}
	}
	for(int i=0;i<n;i++)
	{
		string s;
		cin>>s;
		for(int j=0;j<n;j++)
		{
			b[i][j]=s[j]-'0';
		}
	}
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt+=a[i][n-1];
		if(i!=n-1)cnt+=a[n-1][i];
	}
	if(cnt<n)
	{
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				a[i][j]^=1;
				b[i][j]^=1;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		while(!a[n-1][n-1])row(n-1);
		col(n-1);
	}
	cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt+=a[n-1][i];
	}
	while(cnt)
	{
		while(!a[n-1][n-1])row(n-1);
		col(n-1);
		cnt--;
	}
	for(int i=0;i<n;i++)
	{
		col(n-1);
	}
	vector<int> tmp(n-1);
	int need=0;
	for(int i=0;i<n-1;i++)
	{
		int cur=0;
		for(int j=0;j<n-1;j++)
		{
			cur^=a[i][j];
		}
		int tar=0;
		for(int j=0;j<n;j++)
		{
			tar^=b[i][j];
		}
		tar^=((n-1)&1);	
		tmp[i]=(tar^cur);
		need^=tmp[i];
	}
	int tar=0;
	for(int j=0;j<n;j++)
	{
		tar^=b[n-1][j];
	}
	tar^=((n-1)&1);
	if(tar==need)col(n-1);
	for(int i=n-2;i>=0;i--)
	{
		if(tmp[i])row(n-1);
		col(n-1);
	}
	for(int i=0;i<n-1;i++)
	{
		vector<int> cur;
		for(int j=0;j<n;j++)
		{
			if(a[j][n-1]==b[j][i])row(j);
			else cur.pb(j);
		}
		for(int j=0;j<n;j++)
		{
			col(n-1);
		}
		for(auto x:cur)
		{
			row(x);
		}
	}
	writech(ans.size(),'\n');
	for(auto x:ans)
	{
		printf(x.first?"column ":"row ");
		printf("%lld\n",x.second+1);
	}
	Code by MCYYDS
}

posted @ 2026-07-20 16:48  MCYYDS  阅读(1)  评论(0)    收藏  举报