CodeForces 425B Sereja and Table(枚举)

满足条件的矩阵有一个性质,就是相邻的两行(列)要么完全相同,要么完全相反,所以就枚举每行做为模式串,去把其他行都改为和模式串相同或完全相反的。

注意最优的模式串可能是行的也可能是列的,所以要对行列都做。

而且还有一种数据 比如:

0 0 0 1

0 0 1 0

0 1 0 0

1 0 0 0

也就是说模式串可能既不是某行也不是某列,而是全0或者全1。所以最后再判断一下这两种。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
#include <algorithm>

int a[105][105];

int main(){
	int N,M,K;
	scanf("%d%d%d",&N,&M,&K);
	for(int i=1;i<=N;i++){
		for(int j=1;j<=M;j++){
			scanf("%d",&a[i][j]);
		}
	}
	int tmp[105];
	int res=10000000;
	for(int i=1;i<=N;i++){
		for(int j=1;j<=M;j++){
			tmp[j]=a[i][j];
		}
		int num=0;
		for(int j=1;j<=N;j++){
			int cur=0;
			for(int k=1;k<=M;k++){
				if(a[j][k]!=tmp[k]) cur++;
			}
			num+=min(cur,M-cur);
		}
		res=min(res,num);
	}
	for(int i=1;i<=M;i++){
		for(int j=1;j<=N;j++){
			tmp[j]=a[j][i];
		}
		int num=0;
		for(int j=1;j<=M;j++){
			int cur=0;
			for(int k=1;k<=N;k++){
				if(a[k][j]!=tmp[k]) cur++;
			}
			num+=min(cur,N-cur);
		}
		res=min(res,num);
	}
	int num=0;
	for(int i=1;i<=N;i++){
		int cur=0;
		for(int j=1;j<=M;j++){
			if(a[i][j]) cur++;
		}
		num+=min(cur,M-cur);
	}
	res=min(num,res);
	num=0;
	for(int i=1;i<=N;i++){
		int cur=0;
		for(int j=1;j<=M;j++){
			if(!a[i][j]) cur++;
		}
		num+=min(cur,M-cur);
	}
	res=min(num,res);
	if(res>K) printf("-1");
	else printf("%d",res);
	return 0;
}
/*
3 10 7
0 1 0 0 1 0 1 0 0 0
0 0 1 1 0 0 0 1 0 1
1 0 1 1 1 0 1 1 0 0
*/

你可能感兴趣的:(CodeForces 425B Sereja and Table(枚举))