luogu P1169 [ZJOI2007]棋盘制作

传送门

交叉非常好维护 可以转化成最大矩形面积 ——单调栈!

至于最大正方形面积 每次求矩形面积的时候找比较小的边平方就OK

Code:

 1 // luogu-judger-enable-o2
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<vector>
 8 #define ms(a,b) memset(a,b,sizeof a)
 9 #define rep(i,a,n) for(int i = a;i <= n;i++)
10 #define per(i,n,a) for(int i = n;i >= a;i--)
11 #define inf 2147483647
12 using namespace std;
13 typedef long long ll;
14 ll read() {
15     ll as = 0,fu = 1;
16     char c = getchar();
17     while(c < '0' || c > '9') {
18         if(c == '-') fu = -1;
19         c = getchar();
20     }
21     while(c >= '0' && c <= '9') {
22         as = as * 10 + c - '0';
23         c = getchar();
24     }
25     return as * fu;
26 }
27 const int N = 2005;
28 //head
29 int n,m;
30 bool a[N][N];
31 int h[N];
32 int stk[N],top;
33 int maxq,maxj;
34 int main() {
35     n = read();
36     m = read();
37     rep(i,1,n) rep(j,1,m) a[i][j] = read();
38     rep(i,1,n) {
39     rep(j,1,m) {
40         if(i > 1 && a[i][j] ^ a[i-1][j]) h[j]++;
41         else h[j] = 1;
42     }
43     int cur = 1;
44     while(cur <= m) {
45         top = 0;
46         stk[top] = cur - 1;
47         stk[++top] = cur++;
48         while(cur <= m && (a[i][cur] ^ a[i][cur-1])) {
49         while(top && h[stk[top]] > h[cur]) {
50             int tmp = min(h[stk[top]],cur - stk[top-1] - 1);
51             maxq = max(maxq,tmp * tmp);
52             maxj = max(maxj,h[stk[top]] * (cur-stk[top-1] - 1));
53             top--;
54         }
55         stk[++top] = cur++;
56         }
57         while(top) {
58         int tmp = min(h[stk[top]],cur - stk[top-1] - 1);
59         maxq = max(maxq,tmp * tmp);
60         maxj = max(maxj,h[stk[top]] * (cur - stk[top-1] - 1));
61         top--;
62         }//不合法就弹光
63     }
64     }
65     printf("%d\n%d\n",maxq,maxj);
66     return 0;
67 }

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/9755535.html