题意是给你一个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
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- 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
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<
size()<<"\n"; - for(auto it:v) cout<
" "<" "<" "<"\n"; - }
- return 0;
- }
- /*
- 1的左边或者上面必须要有0
- 连续的1
-
- */