CF1439A2题解
:在中文句子后补充了句号。
:更改了矩阵的表达方式。
首先,看到要在 步内完成,所以平均一步要做好一个点。
其次,不能想到前 行可以用如下方法解决:
- 设当前位是 ,如果 ,则将 取反(特别的,当 时,将 取反),将操作加入答案。
步数一定是小于等于 的,不会超。
正确性等会证明。
为什么是前 行,不是 吗?
因为最后一行不能单独做(第 行下面没有行了),所以要让第 行,第 行配合的做。
接下来就是思考如何做最后两行
自己在草稿纸上画一画,会发现一个 的矩阵无论初始状态是这样的,都可以消除。
所以,我们可以将最后两行分割成 的矩阵,分开来做。
但是,如果 是奇数,则会剩下一列,怎么办呢?其实很简单,我们把这一列单独拿出来做。
不妨做第一列,则如果 (第 行第 列)为 ,将 取反,将操作加入答案。
同理可做 。
接下来,就把矩阵分成若干个 的小矩阵,易得到当矩阵为:
时所需步数最多,为 ,发现也不会超。
解法的正确性证明
首先,易得把剩下矩阵分成若干个 的小矩阵是可行的(自己在草稿纸上画一画,步数证明上文也有讲)。
其次,单独做一列也是可行的,因为改变后面的小矩阵仍然可以做。
最后同理,做前 行时也不会造成什么后果。
代码
#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;
}

浙公网安备 33010602011771号