zoukankan      html  css  js  c++  java
  • 【BZOJ】1057 [ZJOI2007]棋盘制作(悬线法)

    题目

    传送门:QWQ

    分析

    先把题目给出的矩阵变换一下,如果$ a[i][j] $中$ i+j mod 2 = 1 $那么就对$ a[i][j] $取一下反。

    接着就是求原图中最大的0、1子矩阵

    详见lrj蓝书,悬线法维护最大0、1子矩阵。

    代码

     1 #include<bits/stdc++.h>
     2 #define left lft
     3 #define right rght
     4 using namespace std;
     5 const int maxn=2000;
     6 int left[maxn][maxn], right[maxn][maxn], up[maxn][maxn] ;
     7 int mp[maxn][maxn];
     8 int sqr(int x){return x*x;}
     9 int main(){
    10     int n,m;scanf("%d%d",&n,&m);
    11     for(int i=1;i<=n;i++)
    12         for(int j=1;j<=m;j++){
    13             scanf("%d",&mp[i][j]); if((i+j)%2) mp[i][j]^=1;
    14     }
    15     int ans1=0,ans2=0;
    16     for(int i=0;i<=m;i++) right[0][i]=1e9;
    17     for(int i=1;i<=n;i++){
    18         left[i][1]=0; right[i][m]=m;
    19         int le=0,ri=m+1;
    20         for(int j=1;j<=m;j++){
    21             if(mp[i][j]){
    22                 up[i][j]=up[i-1][j]+1; left[i][j]=max(left[i-1][j],le+1);
    23 
    24             }
    25             else{ le=j; }
    26         }
    27 
    28         for(int j=m;j>=1;j--){
    29             if(mp[i][j]){
    30                 right[i][j]=min(ri-1,right[i-1][j]);
    31                 int linelen=right[i][j]-left[i][j]+1 ,rowlen=up[i][j];
    32                 ans1=max(ans1,sqr(min(linelen,rowlen)));
    33                 ans2=max(ans2,linelen*rowlen);
    34             }
    35             else{
    36                 ri=j; right[i][j]=m;
    37             }
    38         }
    39     }
    40 
    41     memset(right,0,sizeof(right)); memset(left,0,sizeof(left)); memset(up,0,sizeof(up));
    42     for(int i=0;i<=m;i++) right[0][i]=1e9;
    43     for(int i=1;i<=n;i++){
    44         left[i][1]=0; right[i][m]=m;
    45         int le=0,ri=m+1;
    46         for(int j=1;j<=m;j++){
    47             if(!mp[i][j]){
    48                 up[i][j]=up[i-1][j]+1; left[i][j]=max(left[i-1][j],le+1);
    49 
    50             }
    51             else{ le=j; }
    52         }
    53 
    54         for(int j=m;j>=1;j--){
    55             if(!mp[i][j]){
    56                 right[i][j]=min(ri-1,right[i-1][j]);
    57                 int linelen=right[i][j]-left[i][j]+1 ,rowlen=up[i][j];
    58                 ans1=max(ans1,sqr(min(linelen,rowlen)));
    59                 ans2=max(ans2,linelen*rowlen);
    60             }
    61             else{
    62                 ri=j; right[i][j]=m;
    63             }
    64         }
    65     }
    66     printf("%d
    %d",ans1,ans2);
    67 
    68     return 0;
    69 }
  • 相关阅读:
    断开ssh链接在后台继续运行命令
    linux 隐藏显示终端光标
    shell脚本中echo显示内容带颜色
    Linux/Unix下pid文件作用浅析
    使用autotools自动生成Makefile并在此之上使用dh-make生成可发布的deb程序包(详解)
    Linux的tmpfs文件系统
    kernel编译
    Qt之读取配置文件
    android之TCP客户端框架
    android之模拟器更新底层
  • 原文地址:https://www.cnblogs.com/noblex/p/9415998.html
Copyright © 2011-2022 走看看