太阳能电池板网格优化
题意:给定 \(n \times n\) 的 \(01\) 矩阵 \(A\) 和 \(B\),可以进行两种操作:
- \(\text{row}(i)\) 表示将 \(A\) 的第 \(i\) 行循环左移一位,如:
\[\begin{bmatrix}
1 & 1 & 0 \\
\color{red}{1} & \color{green}{0} & \color{blue}{1} \\
1 & 1 & 0
\end{bmatrix}
\to
\begin{bmatrix}
1 & 1 & 0 \\
\color{green}{0} & \color{blue}{1} & \color{red}{1} \\
1 & 1 & 0
\end{bmatrix}
\]
- \(\text{column}(i)\) 表示将 \(A\) 的第 \(i\) 列循环下移一位后,反转第 \(i\) 列最上面的一位,如:
\[\begin{bmatrix}
1 & \color{red}{1} & 0 \\
1 & \color{green}{0} & 1 \\
1 & \color{blue}{1} & 0
\end{bmatrix}
\to
\begin{bmatrix}
1 & \color{blue}{0} & 0 \\
1 & \color{red}{1} & 1 \\
1 & \color{green}{0} & 0
\end{bmatrix}
\]
你要在 \(1000\) 次操作内将 \(A\) 变成 \(B\),\(n \leq 20\)。
下面定义一些基本函数:
-
\(\text{revcolumn}(i)\):执行 \(n\) 次 \(\text{column}(i)\),可以反转第 \(i\) 列。
-
\(\text{xorrow}(i)\):第 \(i\) 行的所有数异或和。
考虑我们如何构造一个特定的列,假设矩阵为:
\[\begin{bmatrix}
1 & 1 & 0 \\
1 & 0 & 1 \\
1 & 1 & 0
\end{bmatrix}
\]
我们要构造一列:
\[\begin{bmatrix}
1 \\
0 \\
0
\end{bmatrix}
\]
- 先将最后一列中符合要求的行左移一位
\[\begin{bmatrix}
1 & 1 & 0 \\
1 & 0 & 1 \\
\color{red}{1} & \color{red}{0} & \color{red}{1}
\end{bmatrix}
\]
- 反转最后一列:
\[\begin{bmatrix}
1 & 1 & \color{red}{1} \\
1 & 0 & \color{red}{0} \\
1 & 0 & \color{red}{0}
\end{bmatrix}
\]
- 左移第一步中未左移的行
\[\begin{bmatrix}
\color{red}{1} & \color{red}{1} & \color{red}{1} \\
\color{red}{0} & \color{red}{0} & \color{red}{1} \\
1 & 0 & 0
\end{bmatrix}
\]
容易发现此时矩阵的第 \(n-1\) 列满足要求,且过程中会改变所有的 \(\text{xorrow}(i)\)。
我们可以通过这种方法修改前 \(n-1\) 列,对于最后一列我们算出需要的 \(\text{xorrow}\)。
问题变为对每一行获得需要的奇偶性,分为以下步骤:
- 清空第 \(n\) 列
使用刚才的做法即可,
- 清空第 \(n\) 行
找到第 \(n\) 行的 \(1\),使用 \(\text{row}\) 操作将 \(1\) 放到 \((n,n)\),然后转第 \(n\) 列。
- 反转第 \(n\) 列
使用 \(\text{revcolumn}\) 即可
- 改变第 \(1\) 行到第 \(n-1\) 行的奇偶性
依次考虑第 \(n-1\) 行到第 \(1\) 行,是需要 \(0\) 还是需要 \(1\),如果需要 \(1\) 则搬 \(0\)。
- 改变第 \(n\) 行的奇偶性
此时的第 \(n\) 行必然有一个 \(1\)。
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
bool a[30][30],b[30][30],tar[30];
struct Node{
string op;
int num;
};
vector<Node> ans;
bool tmp[30];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
char ch;
cin>>ch;
if(ch=='1'){
a[i][j]=true;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
char ch;
cin>>ch;
if(ch=='1'){
b[i][j]=true;
tar[i]=!tar[i];
}
}
if(n%2==0){
tar[i]=!tar[i];
}
}
for(int i=1;i<=n;i++){
if(a[i][1]==false){
ans.push_back((Node){"row",i});
for(int j=1;j<n;j++){
a[i][j]=a[i][j+1];
}
a[i][n]=false;
tmp[i]=true;
}
}
for(int i=1;i<=n;i++){
ans.push_back((Node){"column",1});
a[i][1]=!a[i][1];
}
for(int i=1;i<=n;i++){
if(tmp[i]==false){
ans.push_back((Node){"row",i});
for(int j=1;j<n;j++){
a[i][j]=a[i][j+1];
}
a[i][n]=false;
}
}
int cnt_1=0;
for(int i=1;i<=n;i++){
if(a[n][i]==true){
cnt_1++;
}
}
while(cnt_1){
while(a[n][n]!=true){
ans.push_back((Node){"row",n});
bool tmp_num=a[n][1];
for(int i=1;i<n;i++){
a[n][i]=a[n][i+1];
}
a[n][n]=tmp_num;
}
ans.push_back((Node){"column",n});
a[n][n]=false;
cnt_1--;
}
for(int i=1;i<=n;i++){
ans.push_back((Node){"column",n});
a[i][n]=true;
}
cnt_1=0;
for(int i=1;i<n;i++){
bool tmp=false;
for(int j=1;j<n;j++){
if(a[i][j]){
tmp=!tmp;
}
}
if(tmp!=tar[i]){
cnt_1++;
}
}
if(cnt_1%2==tar[n]){
ans.push_back((Node){"column",n});
a[1][n]=false;
}
for(int i=n-1;i>=1;i--){
bool tmp=false;
for(int j=1;j<n;j++){
if(a[i][j]){
tmp=!tmp;
}
}
if(tmp!=tar[i]){
cnt_1++;
ans.push_back((Node){"row",n});
bool tmp_num=a[n][1];
for(int j=1;j<n;j++){
a[n][j]=a[n][j+1];
}
a[n][n]=tmp_num;
}
ans.push_back((Node){"column",n});
bool tmp_num=a[n][n];
for(int j=n-1;j>=1;j--){
a[j+1][n]=a[j][n];
}
a[1][n]=!tmp_num;
}
for(int i=1;i<n;i++){
for(int j=1;j<=n;j++){
if(a[j][n]==b[j][i]){
ans.push_back((Node){"row",j});
bool tmp_num=a[j][1];
for(int k=1;k<n;k++){
a[j][k]=a[j][k+1];
}
a[j][n]=tmp_num;
tmp[j]=true;
}
else{
tmp[j]=false;
}
}
for(int j=1;j<=n;j++){
ans.push_back((Node){"column",n});
a[j][n]=!a[j][n];
}
for(int j=1;j<=n;j++){
if(tmp[j]==false){
ans.push_back((Node){"row",j});
bool tmp_num=a[j][1];
for(int k=1;k<n;k++){
a[j][k]=a[j][k+1];
}
a[j][n]=tmp_num;
}
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
cout<<ans[i].op<<" "<<ans[i].num<<endl;
}
return 0;
}

浙公网安备 33010602011771号