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

    1057: [ZJOI2007]棋盘制作

    Time Limit: 20 Sec  Memory Limit: 162 MB

    Description

      国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源
    于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。而我们的主人公小Q,
    正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定
    将棋盘扩大以适应他们的新规则。小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种
    颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。不过小Q还没有决定是找
    一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他
    希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。于是小Q找到了即将参加全
    国信息学竞赛的你,你能帮助他么?

    Input

      第一行包含两个整数N和M,分别表示矩形纸片的长和宽。接下来的N行包含一个N * M的01矩阵,表示这张矩形
    纸片的颜色(0表示白色,1表示黑色)。

    Output

      包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋
    盘的面积(注意正方形和矩形是可以相交或者包含的)。

    Sample Input

    3 3
    1 0 1
    0 1 0
    1 0 0

    Sample Output

    4
    6

    HINT

    N, M ≤ 2000

    首先有一个很奇妙的变换, 因为题目要求的是黑白相间的,我们对 横坐标与纵坐标和为偶数的格子颜色取反

    这样题目就转化为了颜色相同

    我们可以n * m 的时间预处理出  le[i][j] 和 ri[i][j] (分别表示 在第 i 行 第 j 列的格子向左和向右延伸所有格子颜色相同的最远处)

    然后对于每列从上往下扫

    l[i][j] = min(l[i - 1][j], le[i][j]), r[i][j] = min(r[i - 1][j], ri[i][j])

    表示当前这个上边界固定的矩形最左端和最右端

    如果一个矩形的面积是最大的,它的上边界一定会触碰到一个障碍,所以从每个障碍往下计算一定不会漏解

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define LL long long
      6 
      7 using namespace std;
      8 
      9 const int MAXN = 2e3 + 10;
     10 int N, M;
     11 int ans1 = 0, ans2 = 0;
     12 int map[MAXN][MAXN];
     13 int le[MAXN][MAXN], ri[MAXN][MAXN], h[MAXN][MAXN];
     14 int l[MAXN][MAXN], r[MAXN][MAXN];
     15 inline LL read()
     16 {
     17     LL x = 0, w = 1; char ch = 0;
     18     while(ch < '0' || ch > '9') {
     19         if(ch == '-') {
     20             w = -1;
     21         }
     22         ch = getchar();
     23     }
     24     while(ch >= '0' && ch <= '9') {
     25         x = x * 10 + ch - '0';
     26         ch = getchar();
     27     }
     28     return x * w;
     29 }
     30 
     31 void work(int x)
     32 {
     33     for(int i = 1; i <= N; i++) {
     34         int last = 0;
     35         for(int j = 1; j <= M; j++) {
     36             if(map[i][j] == x) {
     37                 last = j;
     38             }
     39             le[i][j] = last;
     40         }
     41         last = M + 1;
     42         for(int j = M; j >= 1; j--) {
     43             if(map[i][j] == x) {
     44                 last = j;
     45             }
     46             ri[i][j] = last;
     47         }
     48     }
     49     /*for(int i = 1; i <= N; i++) {
     50         for(int j = 1; j <= M; j++) {
     51             cout<<le[i][j]<<" "<<ri[i][j]<<" ";
     52         }
     53         cout<<endl;
     54     }
     55     cout<<endl<<endl;*/
     56     for(int j = 1; j <= M; j++) {
     57         r[0][j] = M + 1;
     58     }
     59     for(int j = 1; j <= M; j++) {
     60         for(int i = 1; i <= N; i++) {
     61             if(map[i][j] == x) {
     62                 h[i][j] = 0;
     63                 l[i][j] = 0, r[i][j] = M + 1;
     64             } else {
     65                 h[i][j] = h[i - 1][j] + 1;
     66                 l[i][j] = max(le[i][j], l[i - 1][j]);
     67                 r[i][j] = min(ri[i][j], r[i - 1][j]);
     68                 int w = r[i][j] - l[i][j] - 1;
     69                 //cout<<h[i][j]<<" "<<l[i][j]<<" "<<r[i][j]<<" ";
     70                 ans1 = max(ans1, min(w, h[i][j]) * min(w, h[i][j]));
     71                 ans2 = max(ans2, h[i][j] * w);
     72             }
     73         }
     74         //cout<<endl;
     75     }
     76     //cout<<endl;
     77 }
     78 int main()
     79 {
     80     N = read(), M = read();
     81     for(int i = 1; i <= N; i++) {
     82         for(int j = 1; j <= M; j++) {
     83             map[i][j] = read();
     84             if((i + j) % 2 == 0) {
     85                 map[i][j] = map[i][j] ^ 1;
     86             }
     87         }
     88     }
     89     /*for(int i = 1; i <= N; i++) {
     90         for(int j = 1; j <= M; j++) {
     91             cout<<map[i][j]<<" ";
     92         }
     93         cout<<endl;
     94     }*/
     95     work(1);
     96     work(0); 
     97     printf("%d
    %d
    ", ans1, ans2);
     98     return 0;
     99 }
    100 
    101 
    102 /*
    103 
    104 3 3
    105 1 0 1
    106 0 1 0
    107 1 0 0
    108 
    109 
    110 */
    View Code
  • 相关阅读:
    CSS规范
    CSS规范
    CSS规范
    CSS function--(来自网易)
    CSS reset--(来自网易)
    js截取图片上传(仅原理)----闲的无聊了代码就不共享了!写的难看,不好意思给你们看了(囧)
    作业:JavaScript(数组篇-poker)给我的徒弟出个题。。。记得早点写完,然后大家3人可以早点打牌了
    BAT及各大互联网公司2014前端笔试面试题--JavaScript篇(昨天某个群友表示写的简单了点,然后我无情的把他的抄了一遍)
    BAT及各大互联网公司2014前端笔试面试题--Html,Css篇(昨天有个群友表示写的简单了点,然后我无情的把他的抄了一遍)
    本日吐槽!“人傻钱多”的P2P公司是否是程序员的合适选择(群聊天记录的娱乐)
  • 原文地址:https://www.cnblogs.com/wuenze/p/8639372.html
Copyright © 2011-2022 走看看