51nod-1316 回文矩阵

思路:预处理出所有的行和列分别为row,col的情况,再遍历所有情况,之中遍历矩阵A[i][j],对于行i,列j是否选取分情况讨论:

                                                    

一,行i,列j都选取。对于上图,行0和列0被选中,此时改变S[0][0],受影响的有S[0][3],S[3][0]因此需要对这三个值进行判断取最小改变值,此外还有另一种情况,当行3或列3也是被选中的时,受影响的就还有S[3][3],这是就需要对4个值来判断。

二,行i被选取。对于行0被选取,同样分两种情况:列3是否选取。即列m-j-1是否选取

三,列j被选取。分行n-i-1是否选取讨论

Code :

#include<iostream>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;

const int MAX_N=10;
const int MAX_M=10;
int n,m,row,col;
string a[MAX_N],d[MAX_N];
vector<int> vr,vc;
bool br[MAX_M],bc[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>row>>col>>n;
	for(int i=0;i<n;++i)
	{
		cin>>a[i];
		d[i]=a[i];
	}
	m=a[0].size();
	for(int i=0;i<(1<<n);++i)
	{
		int t=0,p=i;
		while(p){
			if(p%2==1)	t++;
			p>>=1;
		}
		if(t==row)	vr.push_back(i);
	}
	for(int i=0;i<(1<<m);++i)
	{
		int t=0,p=i;
		while(p){
			if(p%2==1)	t++;
			p>>=1;
		}
		if(t==col)	vc.push_back(i);
	}
	int ans=n*m;
	for(auto r:vr)
	{
		int rr=r;
		memset(br,0,sizeof(br));
		for(int i=0;r;r>>=1,++i)
			if(r%2)	br[i]=true;
		for(auto c:vc)
		{
			memset(bc,0,sizeof(bc));
			for(int i=0;i<n;++i)
				a[i]=d[i];
			for(int i=0;c;c>>=1,++i)
				if(c%2)	bc[i]=true;
			int ss=0;
			for(int i=0;i<n;++i)
				for(int j=0;j<m;++j)
				{
					int t=0,sum=0;
					if(br[i]&&bc[j]){
						sum=a[i][j]-'0'+a[i][m-j-1]-'0'+a[n-i-1][j]-'0';
						if(br[n-i-i]||bc[m-j-1]){
							sum+=a[n-i-1][m-j-1]-'0';
							ss+=min(sum,4-sum);
							if(sum>2)	t=1;
							a[n-i-1][m-j-1]=char(t+'0');
						}else{
							ss+=min(sum,3-sum);
							if(sum>1)	t=1;
						}
						a[i][j]=a[i][m-j-1]=a[n-i-1][j]=char(t+'0');
					}else	if(br[i]){
						sum=a[i][j]-'0'+a[i][m-j-1]-'0';
						if(bc[m-j-1]){
							sum+=a[n-i-1][m-j-1]-'0';
							ss+=min(sum,3-sum);
							if(sum>1)	t=1;
							a[n-i-1][m-j-1]=char(t+'0');
						}else{
							ss+=min(sum,2-sum);
							if(sum>1)	t=1;
						}
						a[i][j]=a[i][m-j-1]=char(t+'0');
					}else	if(bc[j]){
						sum=a[i][j]-'0'+a[n-i-1][j]-'0';
						if(br[n-i-1]){
							sum+=a[n-i-1][m-j-1]-'0';
							ss+=min(sum,3-sum);
							if(sum>1)	t=1;
							a[n-i-1][m-j-1]=char(t+'0');
						}else{
							ss+=min(sum,2-sum);
							if(sum>1)	t=1;
						}
						a[i][j]=a[n-i-1][j]=char(t+'0'); 
					}
				}
			ans=min(ans,ss);
		}
	}
	cout<<ans<<endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/81457757