IndiaHacks 2nd Elimination 2017- A. Binary Blocks

117 阅读1分钟

题意:

对于给出的矩阵,选择一个整数k,为了使每个k*k正方形里的数字全为1或者全为0,你需要变换某些不一样的数字,求变换的最少次数。当n或者m不能整除k时,可以延长到整除为止,延长部分数字为0;注意是最少次数,所以要找到最合适的k。

思路:

 先打表,算出每个位置所包含的数字1的数目,之后在计算每个方块的数字时,只需要用相减的方法就可以算出来,不用再遍历。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char ma[5005][5005];
int biao[5005][5005];
int n,m,k,co,mi=100000000;
void yu(){
	for(int i=1;i<=5000;i++)
		for(int j=1;j<=5000;j++)
			if(ma[i][j]=='1') biao[i][j]=biao[i][j-1]+1;
			else biao[i][j]=biao[i][j-1];
	for(int j=1;j<=5000;j++)
		for(int i=1;i<5000;i++)
			biao[i][j]=biao[i][j]+biao[i-1][j];
}


int sea(int dx,int dy){
	for(int k=2;k<=max(dx,dy);k++){
		co = 0;
		for(int i=k;i-k< dx;i+=k)
			for(int j=k;j-k<dy;j+=k){
				int temp=biao[i][j]-biao[i-k][j]-biao[i][j-k]+biao[i-k][j-k];	
				co+=min(temp,k*k-temp);
			}
		if (co<mi) 		
		mi=co;
	} 
	return mi;			
}
int main(){
	scanf("%d %d",&n,&m);
	memset(biao,0,sizeof(biao));
	memset(ma,0,sizeof(ma));
	for(int i=1;i<=n;i++)
	 	scanf("%s",ma[i]+1);
	 yu();
	printf("%d\n",sea(n,m));
	return 0;
}


\