BZOJ2241 SDOI2011 打地鼠 枚举

题意:给定一个N*M数字矩阵,求一个全1矩阵,使得该矩阵在经过复制后,在满足每次放置的位置不存在0的情况下,放置的矩阵数最少,求最少次数。

题解:由于数据很小所以可以暴力枚举所求矩阵的长和宽然后检验。由于所求矩阵的大小一定是所有数和的因数,然后矩阵越大放的次数就越少,所以倒序枚举。

#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=100+2;
int a[MAXN][MAXN],b[MAXN][MAXN],N,M,S,Ans=INT_MAX;

bool Check(int x,int y){
    memcpy(b,a,sizeof(b));
    for(int i=1;i<=N;i++)
        for(int j=1,t;j<=M;j++){
            t=b[i][j];
            if(t && i+x-1<=N && j+y-1<=M)
                for(int l=i;l<=i+x-1;l++)
                    for(int r=j;r<=j+y-1;r++){
                        b[l][r]-=t;
                        if(b[l][r]<0) return 0;
                    }
            if(b[i][j]) return 0;
        }
    return 1;
}

int main(){
    scanf("%d %d",&N,&M);
    for(int i=1;i<=N;i++)
        for(int j=1;j<=M;j++)
            scanf("%d",a[i]+j),S+=a[i][j];

    for(int i=N;i;i--)
        for(int j=M;j;j--)
            if(S%(i*j)==0 && S/(i*j)<Ans && Check(i,j)) Ans=S/(i*j);
    cout << Ans << endl;

    return 0;
}
View Code

 

posted @ 2017-03-11 16:18  WDZRMPCBIT  阅读(133)  评论(0编辑  收藏  举报