BZOJ 1057

先膜拜这位大犇的解法:

http://www.2cto.com/kf/201412/358274.html


具体做法:
1. 因为要求0,1交替我们先在读入时做if((i+j)%2==0)a[i][j]^=1;之后我们只需求最大的全0或全1矩阵/正方形即可。
2. 我们用i枚举0/1,然后类似简单DP的方法求出j行及以上第k列有f[]个连续0/1。
3. 用R[]/L[]记录最右边/最左边大于等于f[]的列数。
4. 最后判断改变ans,anss的值即可。

以下是代码菌(≧▽≦)/

/**************************************************************
    Problem: 1057
    User: fantasticwtl
    Language: C++
    Result: Accepted
    Time:2612 ms
    Memory:16532 kb
****************************************************************/

#include <cstdio>
#include <cstring>
using namespace std;
int n,m,ans,anss,a[2005][2005],f[2005],L[2005],R[2005];
void LG ()
{
    for(int i=0;i<=1;i++){
        memset(f,0,sizeof(f));
        for(int j=1;j<=n;j++){
            for(int k=1;k<=m;k++)
             if(a[j][k]==i)f[k]=f[k]+1;else f[k]=0;//第二步
            for(int k=1;k<=m;k++){
                L[k]=k;
                while(L[k]-1>=1&&f[L[k]-1]>=f[k])L[k]=L[L[k]-1];
            }
            for(int k=m;k>=1;k--){
                R[k]=k;
                while(R[k]+1<=m&&f[R[k]+1]>=f[k])R[k]=R[R[k]+1];
            }//第三步
            for(int k=1;k<=m;k++){
                int s=f[k]*(R[k]-L[k]+1),g=R[k]-L[k]+1;
                int ss=f[k]>g?g:f[k];
                ss=ss*ss;
                if(s>ans)ans=s;
                if(ss>anss)anss=ss;
            }//第四步
        }
    }
}
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]);
         if((i+j)%2==0)a[i][j]^=1;//第一步
     }//输入部分
    LG ();
    printf("%d\n%d\n",anss,ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值