タイトルの説明:クリックして入力
題名
サイズn×mのバイナリテーブルを作成します。このテーブルは、シンボル0とシンボル1で構成されています。
これを行うことができます:
2×2の正方形に属する3つの異なるセルを選択し、これらのセルのシンボルを変更します(0から1、1から0に変更)。
あなたの仕事は、テーブル内のすべてのシンボルを0に等しくすることです。最大nmの操作を実行できます。
操作の数を最小限に抑える必要はありません。
アイデア
これは前の質問の拡張バージョンです。操作の数がnmに変更されました。前回持っていたコードに問題があり、最適化するしかありませんでしたが、境界処理の最適化のほんの少しでしたが、魔法でした(xy兄弟の言葉で魔法の魔法)つまり、蒸留することができます。)
最適化:境界を判断すると、境界を含む2 * 2の長方形全体が境界線のみに変更されるため、操作回数を減らすことができます。
コード
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define INF 0x3f3f3f3f
#define pii pair<int, int>
//#define pdi pair<double,int>
//#define int long long
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn=1e5+10;
const int mod=1000000007;
int t,n,k,m,tot;
vector<int>ax;
vector<int>ay;
char a[110][110];
int check(int x,int y)
{
int sum=0;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(a[i][j]=='0')
sum++;
}
}
return sum;
}
void check1(int x,int y)
{
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(a[i][j]=='1')
{
ax.push_back(i);
ay.push_back(j);
a[i][j]='0';
}
}
}
}
void check2(int x,int y)
{
int flag=1;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(a[i][j]=='0'||a[i][j]=='1'&&flag)
{
if(a[i][j]=='1') flag--;
ax.push_back(i);
ay.push_back(j);
if(a[i][j]=='0') a[i][j]='1';
else a[i][j]='0';
}
}
}
check1(x,y);
}
void check3(int x,int y)
{
int flag=2;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(flag&&a[i][j]=='0'||a[i][j]=='1')
{
if(a[i][j]=='0') flag--;
ax.push_back(i);
ay.push_back(j);
if(a[i][j]=='0') a[i][j]='1';
else a[i][j]='0';
}
}
}
check2(x,y);
}
void check0(int x,int y)
{
int flag=3;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(flag)
{
flag--;
ax.push_back(i);
ay.push_back(j);
a[i][j]='0';
}
}
}
check3(x,y);
}
int main( )
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
ax.clear();
ay.clear();
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
if(m&1)
{
for(int i=1;i<=n-1;i+=2)
{
int cnt=0;
if(a[i][m]=='1')
{
cnt++;
a[i][m]='0';
ax.push_back(i);
ay.push_back(m);
}
if(a[i+1][m]=='1')
{
cnt++;
a[i+1][m]='0';
ax.push_back(i+1);
ay.push_back(m);
}
if(cnt==0) continue;
else if(cnt==1)
{
if(a[i][m-1]=='0') a[i][m-1]='1';
else a[i][m-1]='0';
ax.push_back(i);
ay.push_back(m-1);
if(a[i+1][m-1]=='0') a[i+1][m-1]='1';
else a[i+1][m-1]='0';
ax.push_back(i+1);
ay.push_back(m-1);
}
if(cnt==2)
{
if(a[i][m-1]=='0') a[i][m-1]='1';
else a[i][m-1]='0';
ax.push_back(i);
ay.push_back(m-1);
}
}
}
if(n&1)
{
for(int j=1;j<=m-1;j+=2)
{
int cnt=0;
if(a[n][j]=='1')
{
cnt++;
a[n][j]='0';
ax.push_back(n);
ay.push_back(j);
}
if(a[n][j+1]=='1')
{
cnt++;
a[n][j+1]='0';
ax.push_back(n);
ay.push_back(j+1);
}
if(cnt==0) continue;
else if(cnt==1)
{
if(a[n-1][j]=='0') a[n-1][j]='1';
else a[n-1][j]='0';
ax.push_back(n-1);
ay.push_back(j);
if(a[n-1][j+1]=='0') a[n-1][j+1]='1';
else a[n-1][j+1]='0';
ax.push_back(n-1);
ay.push_back(j+1);
}
if(cnt==2)
{
if(a[n-1][j]=='0') a[n-1][j]='1';
else a[n-1][j]='0';
ax.push_back(n-1);
ay.push_back(j);
}
}
}
for(int i=1;i<=n-1;i+=2)
{
for(int j=1;j<=m-1;j+=2)
{
int sum=check(i,j);
if(sum==4) continue;
else if(sum==3)
check3(i,j);
else if(sum==2)
check2(i,j);
else if(sum==1)
check1(i,j);
else if(sum==0)
check0(i,j);
}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m-1;j++)
{
int sum=check(i,j);
if(sum==4) continue;
else if(sum==3)
check3(i,j);
else if(sum==2)
check2(i,j);
else if(sum==1)
check1(i,j);
else if(sum==0)
check0(i,j);
}
}
int len=ax.size();
cout<<len/3<<endl;
for(int i=0;i<len;i+=3)
{
cout<<ax[i]<<' '<<ay[i]<<' '<<ax[i+1]<<' '<<ay[i+1]<<' '<<ax[i+2]<<' '<<ay[i+2]<<' '<<endl;
}
}
return 0;
}