【题解】CF1439A2

题目描述

给定一个 n×m01 矩阵,每次操作可以将某个 2×2 的矩阵内的 3 个数取反,请在 n×m 步内将矩阵变为全 0

题解

这种题就是要手推数据啊!还有就是从小的情况入手,看能否拆分子问题。
对于一个2×2的矩阵,我们发现可以用最多四次将它还原。
对于周边余下的1×n1×m的数,先随便怎么还原一下。

#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(!isdigit(w)){
		if(w=='-')f=-1;
		w=getchar();
	}
	while(isdigit(w)){
		j=j*10+w-'0';
		w=getchar();
	}
	return f*j;
}
const int N=200;
struct act{
	int x,y;
};
vector<act>mov[16];
int n,m;
void init(){
	mov[1].push_back((act){2,2});mov[1].push_back((act){2,1});mov[1].push_back((act){1,2});
	mov[2].push_back((act){2,1});mov[2].push_back((act){1,1});mov[2].push_back((act){2,2});
	mov[3].push_back((act){1,2});mov[3].push_back((act){1,1});
	mov[4].push_back((act){1,2});mov[4].push_back((act){1,1});mov[4].push_back((act){2,2});
	mov[5].push_back((act){2,1});mov[5].push_back((act){1,1});
	mov[6].push_back((act){2,1});mov[6].push_back((act){1,2});
	mov[7].push_back((act){2,2});
	mov[8].push_back((act){1,1});mov[8].push_back((act){2,1});mov[8].push_back((act){1,2});
	mov[9].push_back((act){1,1});mov[9].push_back((act){2,2});
	mov[10].push_back((act){1,2});mov[10].push_back((act){2,2});
	mov[11].push_back((act){2,1});
	mov[12].push_back((act){2,1});mov[12].push_back((act){2,2});
	mov[13].push_back((act){1,2});
	mov[14].push_back((act){1,1});
	mov[15].push_back((act){1,1});mov[15].push_back((act){2,2});mov[15].push_back((act){2,1});mov[15].push_back((act){1,2});
	return ;	
}
int X[5]={0,0,0,1,-1};
int Y[5]={0,1,-1,0,0};
char s[N];
bool sum[N][N];
struct Ans{
	int x[3],y[3];
}ans[N*N];
int cnt;
void deal(int a,int b,int x,int y){
	a--,b--;
	int tot=0;
	cnt++;
	for(int i=0;i<5;i++){
		int xx=X[i]+x,yy=Y[i]+y;
		if(xx<1||xx>2||yy<1||yy>2)continue;
		ans[cnt].x[tot]=a+xx,ans[cnt].y[tot]=b+yy;
		sum[a+xx][b+yy]^=1;
		tot++;
	}
	return ;
}
void work(){
	n=rd(),m=rd();
	cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		for(int j=1;j<=m;j++)sum[i][j]=s[j]-'0';
	}
	if(n&1){
		for(int i=1;i<m;i++)if(sum[n][i])deal(n-1,i,1,1);
		if(sum[n][m])deal(n-1,m-1,1,2);
		n--;
	}
	if(m&1){
		for(int i=1;i<n;i++)if(sum[i][m])deal(i,m-1,1,1);
		if(sum[n][m])deal(n-1,m-1,2,1);
		m--;
	}
//	for(int i=1;i<=n+1;i++){
//		for(int j=1;j<=m+1;j++)cout<<sum[i][j]<<" ";
//		cout<<"\n"; 
//	}
	for(int i=1;i<=n;i+=2){
		for(int j=1;j<=m;j+=2){
			int sumn=0;
			sumn=sumn*2+sum[i][j];
			sumn=sumn*2+sum[i][j+1];
			sumn=sumn*2+sum[i+1][j];
			sumn=sumn*2+sum[i+1][j+1];
//			cout<<i<<"-"<<j<<":"<<sumn<<"\n"; 
			for(auto a:mov[sumn])deal(i,j,a.x,a.y);
		}
	}
	printf("%d\n",cnt);
	for(int i=1;i<=cnt;i++){
		for(int j=0;j<3;j++)printf("%d %d ",ans[i].x[j],ans[i].y[j]);
		printf("\n");
	}
	return ;
}
signed main(){
	init();
	int T=rd();
	while(T--)work();
	return 0;
}
/*
1
2 2
00
11
*/
posted @   flywatre  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示