zoukankan      html  css  js  c++  java
  • bzoj 1057: [ZJOI2007]棋盘制作

    首先是对于图上所有的棋盘一定属于以下两种类型:

    1.黑格行列奇偶性相同,白格不同

    2.白格行列奇偶性相同,黑格不同

    那么在输入的时候属于第一种情况的赋1,属于第二种情况的赋0

    统计最大的1或0矩形和正方形就可以啦。

    统计矩形和玉蟾宫是一样的做法,单调栈嘛。

     1 #include <cstdio>
     2 #include <stack>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm> 
     6 using namespace std;
     7 #define N 2008
     8 
     9 int ans1,ans2,n,m,f[N][N],s[N],w[N],top;
    10 bool map[N][N];
    11 
    12 void build()
    13 {
    14     scanf("%d%d",&n,&m);
    15     for (int i = 1;i <= n;i++)
    16         for (int j = 1;j <= m;j++)
    17         {   
    18             int a; scanf("%d",&a);
    19             if ((i & 1) == (j & 1) && a || (i & 1) != (j & 1) && !a) map[i][j] = 1;//& 优先级低于 ==!! 
    20             else map[i][j] = 0;
    21         }
    22     for (int i = 1;i <= n;i++)
    23         for (int j = 1;j <= m;j++)
    24             if (map[i][j]) f[i][j] = f[i][j-1] + 1;
    25             else f[i][j] = 0;
    26 }
    27 
    28 void rebuild()
    29 {
    30     for (int i = 1;i <= n;i++)
    31         for (int j = 1;j <= m;j++)
    32 //            map[i][j] = ~map[i][j]; 不能按位取反!!因为第一位之后的也会取反!!
    33             map[i][j] = !map[i][j];  
    34     for (int i = 1;i <= n;i++)
    35         for (int j = 1;j <= m;j++)
    36             if (map[i][j]) f[i][j] = f[i][j-1] + 1;
    37             else f[i][j] = 0;
    38 }
    39 
    40 inline int sqr(int a)
    41     {return (a*a);}
    42     
    43 void work()
    44 {
    45     for (int j = 1;j <= m;j++)
    46     {
    47         top = 0;
    48         for (int i = 1;i <= n + 1;i++)
    49         {
    50             int minw = i;
    51             while (top && s[top] >= f[i][j])
    52             {
    53                 ans1 = max(ans1,s[top] * (i - w[top]));
    54                 ans2 = max(ans2,sqr(min(s[top],i-w[top])));
    55                 minw = w[top];
    56                 top--;
    57             }
    58             s[++top] = f[i][j]; w[top] = minw;
    59         }
    60     }
    61 }
    62 
    63 void makeline()
    64 {for (int i = 1;i <= m;i++) printf("--");printf("
    ");}
    65 
    66 void debug()
    67 {
    68     makeline();
    69     for (int i = 1;i <= n;i++)
    70     {
    71         for (int j = 1;j <= m;j++) printf("%d ",map[i][j]);
    72         printf("
    ");
    73     }
    74     makeline();
    75     for (int i = 1;i <= n;i++)
    76     {
    77         for (int j = 1;j <= m;j++) printf("%d ",f[i][j]);
    78         printf("
    ");
    79     }
    80 }
    81 
    82 int main()
    83 {
    84 //    freopen("input.txt","r",stdin);
    85     build();
    86 //    debug();
    87     work();
    88     rebuild();
    89 //    debug();
    90     work();
    91     printf("%d
    %d
    ",ans2,ans1);
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    shell去重
    JDBC源码解析
    try catch finally
    URL
    域名与IP地址的联系与区别
    C++stack
    C++vector
    单链表常见面试题(C语言实现)
    数据库limit子句
    strcpy和memcpy的区别
  • 原文地址:https://www.cnblogs.com/wulala979/p/3529377.html
Copyright © 2011-2022 走看看