题解思路:暴力枚举。预处理好用O(1)算出某个矩阵中0的个数就可以了,越界的可以处理出额外0的个数。
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<set>
#include<cmath>
#include<vector>
typedef long long ll;
using namespace std;
const int mx = 2e3+510;
int n,m,mart[mx][mx];
char map[mx][mx];
int main(){
scanf("%d%d",&n,&m);
int maxx = max(n,m), ans = 1e9;
for(int i=1;i<=n;i++) scanf("%s",map[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mart[i][j] = mart[i-1][j]+mart[i][j-1]-mart[i-1][j-1]+(map[i][j]=='0');
for(int i=2;i<=maxx;i++){
int cnt = 0,sum = i*i;
for(int j=1;j<=n;j+=i){
int x = j + i - 1;
for(int k=1;k<=m;k+=i){
int y = k + i - 1,mc = min(m,y),mr = min(n,x);
int po = mart[mr][mc]-mart[mr][k-1]-mart[j-1][mc]+mart[j-1][k-1]+(x-j+1)*(y-k+1)-(mr-j+1)*(mc-k+1);
if(po>sum/2) cnt += sum - po;
else cnt += po;
}
}
ans = min(ans,cnt);
}
printf("%d\n",ans);
return 0;
}