[P1169 [ZJOI2007]] 悬线法

  • 题目链接:P1169 [ZJOI2007]棋盘制作
  • 题目大意:给定一个01棋盘,求其中01交错的最大正方形与矩形。
  • 思路:悬线法
  • 求解正方形&&长方形的情况即可。题目要求01交错,所以"!="即可。
  • 参考代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2005;
int lft[N][N], rgt[N][N], up[N][N], res[N][N];
int main() {
  int n, m, ans_2 = -100, ans_1 = -100;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &res[i][j]);
      lft[i][j] = rgt[i][j] = j;
      up[i][j] = 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 2; j <= m; j++) {
      if (res[i][j] != res[i][j - 1]) {
        lft[i][j] = lft[i][j - 1]; //预处理左边界
      }
    }
    for (int j = m - 1; j >= 1; j--) {
      if (res[i][j] != res[i][j + 1]) {
        rgt[i][j] = rgt[i][j + 1]; //预处理右边界
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (i > 1 && res[i][j] != res[i - 1][j]) {
        lft[i][j] = max(lft[i][j], lft[i - 1][j]);
        rgt[i][j] = min(rgt[i][j], rgt[i - 1][j]);
        up[i][j] = up[i - 1][j] + 1;
      }
      int a = rgt[i][j] - lft[i][j] + 1; //横向长度
      int b = min(a, up[i][j]);          //竖向长度
      // printf("a:%d b:%d\n",a,b);
      ans_1 = max(ans_1, b * b);        //正方形
      ans_2 = max(ans_2, a * up[i][j]); //长方形
      // ans_2 = max(ans_2, (rgt[i][j] - lft[i][j] + 1) * up[i][j]);
    }
  }
  printf("%d\n%d\n", ans_1, ans_2);
  return 0;
}
发布了293 篇原创文章 · 获赞 212 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/nuoyanli/article/details/103513591