CF1439A2题解

2023/6/292023/6/29:在中文句子后补充了句号。

2023/7/62023/7/6:更改了矩阵的表达方式。

首先,看到要在 n×mn\times m 步内完成,所以平均一步要做好一个点。

其次,不能想到前 n2n-2 行可以用如下方法解决:

  • 设当前位是 ai,ja_{i,j},如果 ai,j=1a_{i,j}=1,则将 ai,j,ai+1,j1,ai+1,ja_{i,j},a_{i+1,j-1},a_{i+1,j} 取反(特别的,当 j=1j=1 时,将 ai,j,ai+1,j,ai+1,j+1a_{i,j},a_{i+1,j},a_{i+1,j+1} 取反),将操作加入答案。

步数一定是小于等于 (n2)×m(n-2)\times m 的,不会超。

正确性等会证明。

为什么是前 n2n-2 行,不是 n1n-1 吗?

因为最后一行不能单独做(第 nn 行下面没有行了),所以要让第 n1n-1 行,第 nn 行配合的做。


接下来就是思考如何做最后两行

自己在草稿纸上画一画,会发现一个 2×22\times 2 的矩阵无论初始状态是这样的,都可以消除。

所以,我们可以将最后两行分割成 2×22\times 2 的矩阵,分开来做。

但是,如果 mm 是奇数,则会剩下一列,怎么办呢?其实很简单,我们把这一列单独拿出来做。

不妨做第一列,则如果 an1,1a_{n-1,1}(第 n1n-1 行第 11 列)为 11,将 an1,1,an1,2,an,2a_{n-1,1},a_{n-1,2},a_{n,2} 取反,将操作加入答案。

同理可做 an,1a_{n,1}

接下来,就把矩阵分成若干个 2×22\times 2 的小矩阵,易得到当矩阵为:

1111\begin{vmatrix} 1 & 1 \\ 1 & 1 \end{vmatrix}

时所需步数最多,为 44,发现也不会超。


解法的正确性证明

首先,易得把剩下矩阵分成若干个 2×22\times 2 的小矩阵是可行的(自己在草稿纸上画一画,步数证明上文也有讲)。

其次,单独做一列也是可行的,因为改变后面的小矩阵仍然可以做。

最后同理,做前 n2n-2 行时也不会造成什么后果。

代码

#include<bits/stdc++.h>
using namespace std;
int T,n,m,ans,a[10010][7];
char c[110][110];
void left_up(int i){
    ans++;
    a[ans][1]=n-1;
    a[ans][2]=i;
    a[ans][3]=n-1;
    a[ans][4]=i+1;
    a[ans][5]=n;
    a[ans][6]=i;
}
void left_down(int i){
    ans++;
    a[ans][1]=n-1;
    a[ans][2]=i;
    a[ans][3]=n;
    a[ans][4]=i;
    a[ans][5]=n;
    a[ans][6]=i+1;
}
void right_up(int i){
    ans++;
    a[ans][1]=n-1;
    a[ans][2]=i;
    a[ans][3]=n-1;
    a[ans][4]=i+1;
    a[ans][5]=n;
    a[ans][6]=i+1;
}
void right_down(int i){
    ans++;
    a[ans][1]=n-1;
    a[ans][2]=i+1;
    a[ans][3]=n;
    a[ans][4]=i;
    a[ans][5]=n;
    a[ans][6]=i+1;
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        ans=0;
        for(int i=1;i<=n;i++) scanf("%s",c[i]+1);
        for(int i=1;i<=n-2;i++){
            if(c[i][1]=='1'){
                ans++;
                a[ans][1]=i;
                a[ans][2]=1;
                a[ans][3]=i+1;
                a[ans][4]=1;
                a[ans][5]=i+1;
                a[ans][6]=2;
                if(c[i+1][1]=='0') c[i+1][1]='1';
                else c[i+1][1]='0';
                if(c[i+1][2]=='0') c[i+1][2]='1';
                else c[i+1][2]='0';
            }
            for(int j=2;j<=m;j++){
                if(c[i][j]=='1'){
                    ans++;
                    a[ans][1]=i;
                    a[ans][2]=j;
                    a[ans][3]=i+1;
                    a[ans][4]=j;
                    a[ans][5]=i+1;
                    a[ans][6]=j-1;
                    if(c[i+1][j]=='0') c[i+1][j]='1';
                    else c[i+1][j]='0';
                    if(c[i+1][j-1]=='0') c[i+1][j-1]='1';
                    else c[i+1][j-1]='0';
                }
            }
        }
        if(m&1){
            if(c[n-1][1]=='1'){
                ans++;
                a[ans][1]=n-1;
                a[ans][2]=1;
                a[ans][3]=n-1;
                a[ans][4]=2;
                a[ans][5]=n;
                a[ans][6]=2;
                if(c[n-1][2]=='0') c[n-1][2]='1';
                else c[n-1][2]='0';
                if(c[n][2]=='0') c[n][2]='1';
                else c[n][2]='0';
            }
            if(c[n][1]=='1'){
                ans++;
                a[ans][1]=n;
                a[ans][2]=1;
                a[ans][3]=n-1;
                a[ans][4]=2;
                a[ans][5]=n;
                a[ans][6]=2;
                if(c[n-1][2]=='0') c[n-1][2]='1';
                else c[n-1][2]='0';
                if(c[n][2]=='0') c[n][2]='1';
                else c[n][2]='0';
            }
            for(int i=2;i<m;i+=2){
                if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    left_up(i);
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    right_up(i);
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    left_down(i);
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    right_down(i);
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    left_down(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    right_down(i);
                    right_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    left_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    right_up(i);
                    left_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    left_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    right_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    right_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    left_up(i);
                    left_down(i);
                    right_up(i);
                    right_down(i);
                }
            }
        }
        else{
			for(int i=1;i<m;i+=2){
                if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    left_up(i);
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    right_up(i);
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    left_down(i);
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    right_down(i);
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='0'){
                    left_down(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    right_down(i);
                    right_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    left_up(i);
                    right_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    right_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    left_up(i);
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    right_up(i);
                    left_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='0'){
                    left_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='0'&&c[n][i+1]=='1'){
                    right_up(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='0'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    left_down(i);
                }
                else if(c[n-1][i]=='0'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    right_down(i);
                }
                else if(c[n-1][i]=='1'&&c[n-1][i+1]=='1'&&c[n][i]=='1'&&c[n][i+1]=='1'){
                    left_up(i);
                    left_down(i);
                    right_up(i);
                    right_down(i);
                }
            }
		} 
        printf("%d\n",ans);
        for(int i=1;i<=ans;i++){
            for(int j=1;j<=6;j++) printf("%d ",a[i][j]);
            putchar('\n');
        }
    }
    return 0;
}
posted @ 2023-06-28 20:24  fengxiaoyi  阅读(15)  评论(0)    收藏  举报  来源