题目描述
矿工乐乐发现了一张藏宝图,地图由n行m列 的格子组成,每个格子可能是红宝石(0)、蓝宝石(1)或陷阱(2)。乐乐想挖出一个最大的正方形区域,但必须满足以下两个条件:
|-----------------|
| 1、红蓝宝石数量相等。 |
| 2、区域内没有陷阱。 |你能帮他找到这个正方形的边长吗?若找不到,输出0。
输入格式
第一行两个整数 n 和 m,接下来 n 行每行 m 个数字。
输出格式
最大正方形的边长。
输入/输出例子1
输入:
4 4
1 0 1 0
0 1 0 1
1 0 2 0
0 1 0 1
输出:
2
样例解释
以第1行第1列为左上角,边长为2的正方形。
数据范围
20%,2<=n,m<=40
100%,2<=n,m<=450
参考答案
cpp
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 455;
int mp[MAXN][MAXN];
int sum0[MAXN][MAXN], sum1[MAXN][MAXN], sum2[MAXN][MAXN];
int n, m;
inline void getCnt(int x1, int y1, int x2, int y2, int &c0, int &c1, int &c2)
{
c0 = sum0[x2][y2] - sum0[x1-1][y2] - sum0[x2][y1-1] + sum0[x1-1][y1-1];
c1 = sum1[x2][y2] - sum1[x1-1][y2] - sum1[x2][y1-1] + sum1[x1-1][y1-1];
c2 = sum2[x2][y2] - sum2[x1-1][y2] - sum2[x2][y1-1] + sum2[x1-1][y1-1];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
cin >> mp[i][j];
sum0[i][j] = sum0[i-1][j] + sum0[i][j-1] - sum0[i-1][j-1];
sum1[i][j] = sum1[i-1][j] + sum1[i][j-1] - sum1[i-1][j-1];
sum2[i][j] = sum2[i-1][j] + sum2[i][j-1] - sum2[i-1][j-1];
if(mp[i][j] == 0) sum0[i][j]++;
else if(mp[i][j] == 1) sum1[i][j]++;
else sum2[i][j]++;
}
}
int limit = min(n, m);
for(int L = limit; L >= 2; --L)
{
if(L % 2 != 0) continue;
for(int i = 1; i + L - 1 <= n; ++i)
{
for(int j = 1; j + L - 1 <= m; ++j)
{
int x2 = i + L - 1;
int y2 = j + L - 1;
int c0, c1, c2;
getCnt(i, j, x2, y2, c0, c1, c2);
if(c2 == 0 && c0 == c1)
{
cout << L << endl;
return 0;
}
}
}
}
cout << 0 << endl;
return 0;
}
题目链接:
https://v1.51goc.com/question/viewProgram/118875
(进去后要登录)