#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
}

浙公网安备 33010602011771号