バイナリテーブル(ハードバージョン)-(思考)

タイトルの説明:クリックして入力

題名

サイズ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;
}

おすすめ

転載: blog.csdn.net/Cosmic_Tree/article/details/109772397