codeforces838A-Binary Blocks

题解:先预处理2*max(n,m)的矩阵前缀然后暴力枚举k = 2~max(n,m)的情况求出来需要变更的最小值用矩阵相减求出小每一个小矩阵中的最小值即可

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mx = 5e3+5;
char s[mx][mx];
int a[2][mx][mx];
int main(){
    memset(a,0,sizeof(a));
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++)
        scanf("%s",s[i]+1);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            a[s[i][j]-'0'][i][j]++;
    int d = 2*max(n,m);
    for(int i = 1; i <= d; i++)
        for(int j = 1; j <= d; j++){
            a[0][i][j]+=a[0][i][j-1];
            a[1][i][j]+=a[1][i][j-1];
            if(i>n||j>m)
                a[0][i][j]++;
        }
    for(int i = 1; i <= d; i++)
        for(int j = 1; j <= d; j++){
            a[0][i][j]+=a[0][i-1][j];
            a[1][i][j]+=a[1][i-1][j];
        }
   // for(int i = 1; i <= d; i++)
     //   for(int j = 1; j <= d; j++)
       //     printf("%d%c",a[0][i][j],j==d?'\n':' ');
    d/=2;
    int ans = d*d;
    for(int i = 2; i <= d; i++){
        int sum = 0;
        for(int j = i; j <= d+i; j+=i)
        for(int k = i; k <= d+i; k+=i){
            int num_one = a[1][j][k]+a[1][j-i][k-i]-a[1][j-i][k]-a[1][j][k-i];
            int num_zero = a[0][j][k]+a[0][j-i][k-i]-a[0][j-i][k]-a[0][j][k-i];
            sum += min(num_one,num_zero);
        }
        ans = min(ans,sum);
    }
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值