838A

来源:互联网 发布:什么是大数据举例说明 编辑:程序博客网 时间:2024/06/03 17:49

题意:已知n*m的矩阵,由1,0构成,要求确定一个k,使得n*m的矩阵划分成一系列k*k的小矩阵,并且k*k矩阵内的所有值都要相同(要么都为1,要么都为0)。 (可以补行或列,补0)

思路:遍历k(1~2500) , 对于每一个k,我们处理出当前k所需要改变的所有次数。 首先,我们预处理出(1,1)~(i,j)【任意一点】区域中’1’的个数dp[i][j],那么对于当前k*k的区域,我们所要改变的就是 : dp[i][j]-dp[i-k][j]-dp[i][j-k] + dp[i-k][j-k],对于每一个k,累加比较,求出最小的次数。

错误分析:瞎猜,以为2肯定是最小的,所以k恒等于2 , 然后瞎搞搞就wa了5发。

数据分析:2 ≤ n, m ≤ 2 500 k<=max(n,m) <=2500

复杂度分析: O(k*n/k*m/k)=O(m*n/k) 还是很可观的复杂度

#include <bits/stdc++.h>using namespace std;typedef long long ll;char mp[5050][5050];int n,m;int dp[5050][5050];ll a=0;ll minn=LONG_LONG_MAX;void init() //  预处理——关键{    memset(dp,0,sizeof(dp));    for(int i=1;i<=5050-1;i++)        for(int j=1;j<=5050-1;j++)           dp[i][j]= mp[i][j]=='1' ? dp[i][j-1]+1: dp[i][j-1];    for(int i=1;i<=5050-1;i++)        for(int j=1;j<=5050-1;j++)            dp[i][j]+=dp[i-1][j];}ll solve(){    int t=max(n,m);    for(int k=2;k<=t;k++)    {        a=0;        for(int i=k;i<=n+k ;i+=k)        {            for(int j=k;j<=m+k ;j+=k)            {                int temp=dp[i][j]-dp[i-k][j]-dp[i][j-k]+dp[i-k][j-k];                //printf("k=%d i=%d j=%d temp=%d\n",k,i,j,temp);                a+=1LL*min(temp,k*k-temp);            }        }        if(a<minn)  minn=a;    }    return minn;}int main(void){    cin >> n>> m;    for(int i=1;i<=n;i++)        scanf("%s",mp[i]+1);    init();    /*for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            printf("dp[%d][%d]=%d\n",i,j,dp[i][j]);*/    ll ans=solve();    cout << ans << endl;}
原创粉丝点击