【暴力】codeforces 838A Binary Blocks

CN_swords發表於2017-08-07

Link:http://codeforces.com/problemset/problem/838/A

#include <bits/stdc++.h>
using namespace std;

/*
838A Binary Blocks
題意:給出一個矩陣,值為0或1,可以將矩陣分成多個k*k的小矩陣,小矩陣超出界限的補0,
將每個小矩陣都變成一樣的值,問需要改變最小的次數。
題解:當小矩陣k=2時,明顯比k為2的倍數的改變次數小,因為k越小變動的方法越多,
那麼只要列舉k為所有質數,那麼實質時間複雜度為O(N*N)。
求小矩陣的需要改變的值可以用字首和求1的個數,k*k減一下是0的個數,取1和0比較小的個數。
*/
const int N = 2510;
const int INF = 0x3f3f3f3f;
int prime[400];
bool isprime[N];
int k;
void init(){
    k = 0;
    for(int i = 2; i <= N; i++)
    {
        if(!isprime[i]){
            prime[k++] = i;
            for(int j = i+i; j <= N; j+=i)
                isprime[j] = 1;
        }
    }
}
char s[N];
int ma[N*2][N*2],pre[N*2][N*2];
int main()
{
    init();
    memset(pre,0,sizeof(pre));
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1; i < 2*N; i++)
    {
        if(i <= n)
            scanf("%s",s+1);
        int tmp = 0;
        for(int j = 1; j <= m; j++)
        {
            if(i > n)
                ma[i][j] = 0;
            else
            {
                if(s[j] == '0')
                    ma[i][j] = 0;
                else{
                    ma[i][j] = 1;
                tmp++;
                }
            }
            pre[i][j] = tmp+pre[i-1][j];
        }
        for(int j = m+1; j < N*2; j++)
            pre[i][j] = tmp+pre[i-1][j];
    }
    int ans = INF;
    for(int f = 0; f < k; f++)
    {
        int p = prime[f];
//        printf("%d\n",p);
        int res = 0;
        for(int i = p; i < n+p; i+=p)
        {
            for(int j = p; j < m+p; j+=p)
            {
                int ff = pre[i][j]+pre[i-p][j-p]-pre[i][j-p]-pre[i-p][j];
//                printf("%d %d %d\n",i,j,ff);
                res = res + min(p*p-ff,ff);
            }
        }
//        printf("res = %d\n",res);
        ans = min(ans,res);
    }
    printf("%d\n",ans);
    return 0;
}


相關文章