题意是给你一个01矩阵,按照画象棋的模式能不能把一个全部是0的矩阵变成给的矩阵
这题想的复杂了一点点,其实还好
这题明白了之后发现构造题的漂亮了
首先象棋是010...这种错开的形式,分析可得,最简单的构造方法是01 01的这样构造
所以对于每一个1而言0只会在上面或者左边
而对于一个连续的1来说左边或者上面必有0,除了
011111
111111的这种形式,因为最后一排的第一个1的0可以转化到上面
其实可以直接顺次找到1,然后01这样枚举
但是有连续的1存在,这样做就很麻烦了。现在才是构造的美
可以从最后一个开始(自己模拟一下顺序就知道了),如果碰到1直接加入01的这种(也不考虑上下了),考虑越多情况越复杂,直接限定一个。随后如果1在最边上也就是最左边,那就加入到上面的里面,一直往上走。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#include<iostream>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PAII;
const int N=2e6+10,M=5050,INF=0x3f3f3f3f,mod=998244353;
char ch[M][M];
struct mess{
int x1,y1,x2,y2;
};
vector<mess> v;
int main(){
//IOS;
int T;
//T=1;
cin>>T;
while(T--)
{
v.clear();
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>ch[i][j];
if(ch[1][1]=='1')
{
cout<<"-1\n";
continue;
}
int cnt=0;
for(int i=n;i>=1;i--)
{
for(int j=m;j>=1;j--)
{
if(ch[i][j]=='1')
{
if(j>1) v.push_back({i,j-1,i,j});
else v.push_back({i-1,j,i,j});
}
}
}
cout<<v.size()<<"\n";
for(auto it:v) cout<<it.x1<<" "<<it.y1<<" "<<it.x2<<" "<<it.y2<<"\n";
}
return 0;
}
/*
1的左边或者上面必须要有0
连续的1
*/