来源http://codevs.cn/problem/1159/
去年APUC计算概论考试的H题就由此变式而来,到时写了个自以为O(n^4)实际上n^6的枚举,自然没过,当时如果做出来有A=希望。考完srz神犇告诉我了O(n^3)的算法,并没有听懂。一直懒散,直到今天才研究了一下,发现有位省队爷写过论文,十分详尽。
《对最大全零子矩阵的研究》
http://wenku.baidu.com/link?url=BmVcU3ZfKTabjcsNzYHeOkYoHHCU1EnbGu4JKclaORpNcxxubAr0j9y-aYIL8uCwgyCAFC19SUDTnuDHEZLHAkIG6VrmSL7mbS4zKv_G3jG
想了想写出来了n^3的算法,显然是能过的,但是论文中的法6给我留下深刻印象,抽时间一定要实现一下。
自己写的算是法3吧,srz大神的方法,简单有效,尤其是将二维转化为一维的方法和部分和实现O(1)的判断,给我启发很大。
其实很多题目并没有那么难,这道典型的水题卡住我深刻说明了一些问题。
下面法3的AC代码。原题与H题略有不同。
#include
#include
#include
#include
#include
#include
using namespace std;
int f[2050][2050],ans,n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int b=0,x=0;
for(int j=1;j<=n;j++)
{
cin>>x;
if(!x)
{
b++;
f[i][j]=b;
}
else b=0;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{ if(!f[i][j])
continue;
int p=i,q=i;
while((p>1&&f[p][j])&&f[p-1][j]>=f[i][j])
{
p--;
}
while((q1][j]>=f[i][j])
{
q++;
}
ans=max(ans,(q-p+1)*f[i][j]);
}
}
cout<