暴力大法好!!!
暴力前加了个判断,发现速度并没有快多少
如果长为a宽为b的锤子不行
那么长为a*i宽为b*j的锤子也不行,i,j都是正整数
然后直接暴力就好了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;
int sc()
{
int i=0; char c=getchar();
while( c>'9' || c<'0' ) c=getchar();
while( c>='0'&& c<='9') i=i*10+c-'0',c=getchar();
return i;
}
int a[111][111],b[111][111];
int f[111][111];
int n,m,k,sum,ans;
bool jud(int x,int y)
{
if(sum%(x*y)!=0||ans<=sum/(x*y)) return 0;
return 1;
for(int i=1,p=sqrt(x); i<=p; i++)
if(x%i==0)
{
if(!f[i][y]) return 0;
if(i!=1&&!f[x/i][y]) return 0;
}
for(int i=1,p=sqrt(y); i<=p; i++)
if(y%i==0)
{
if(!f[x][i]) return 0;
if(i!=1&&!f[x][y/i]) return 0;
}
return 1;
}
bool ok(int x,int y)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
b[i][j]=a[i][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(b[i][j])
{
int u=b[i][j];
if(i+x>n+1||j+y>m+1) return 0;
for(int k=i; k<i+x; k++)
for(int l=j; l<j+y; l++)
{
b[k][l]-=u;
if(b[k][l]<0) return 0;
}
}
return 1;
}
int main()
{
n=sc(),m=sc();
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
a[i][j]=sc(),sum+=a[i][j];
f[1][1]=1; ans=sum;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(jud(i,j))
if(ok(i,j))
ans=sum/(i*j),
f[i][j]=1;
cout << ans;
return 0;
}