# BZOJ 1057 棋盘制作

3 3
1 0 1
0 1 0
1 0 0

4
6

## HINT

对于100%的数据，N, M ≤ 2000

 1 for (int i = 1;i <= n;++i)
2     {
3         int lo = 0,ro = m+1;
4         for (int j = 1;j <= m;++j)
5         {
6             if (s[i][j] == sign) up[i][j] = le[i][j] = 0,lo = j;
7             else up[i][j] = i==1?1:up[i-1][j]+1,le[i][j] = i==1?lo+1:max(le[i-1][j],lo+1);
8         }
9         for (int j = m;j;--j)
10         {
11             if (s[i][j] == sign) ri[i][j] = m+1,ro = j;
12             else ri[i][j] = i==1?ro-1:min(ri[i-1][j],ro-1);
13             int a = up[i][j],b = ri[i][j]-le[i][j]+1,p = min(a,b);
14             ans1 = max(ans1,p*p); ans2 = max(ans2,a*b);
15         }
16     }
View Code

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 using namespace std;
5
6 #define maxn 2010
7 int s[maxn][maxn],le[maxn][maxn],ri[maxn][maxn];
8 int up[maxn][maxn],n,m,ans1,ans2;
9
10 inline void work()
11 {
12     for (int i = 1;i <= n;++i)
13     {
14         for (int j = 1;j <= m;++j)
15         {
16             if (i == 1 || s[i][j] == s[i-1][j]) up[i][j] = 1;
17             else up[i][j] = up[i-1][j]+1;
18         }
19     }
20 }
21
22 inline void deal()
23 {
24     for (int i = 1;i <= n;++i)
25         for (int j = 1;j <= m;++j)
26             if ((i + j)&1) s[i][j] ^= 1;
27 }
28
29 inline void work(int sign)
30 {
31     for (int i = 1;i <= n;++i)
32     {
33         int lo = 0,ro = m+1;
34         for (int j = 1;j <= m;++j)
35         {
36             if (s[i][j] == sign) up[i][j] = le[i][j] = 0,lo = j;
37             else up[i][j] = i==1?1:up[i-1][j]+1,le[i][j] = i==1?lo+1:max(le[i-1][j],lo+1);
38         }
39         for (int j = m;j;--j)
40         {
41             if (s[i][j] == sign) ri[i][j] = m+1,ro = j;
42             else ri[i][j] = i==1?ro-1:min(ri[i-1][j],ro-1);
43             int a = up[i][j],b = ri[i][j]-le[i][j]+1,p = min(a,b);
44             ans1 = max(ans1,p*p); ans2 = max(ans2,a*b);
45         }
46     }
47 }
48
49 int main()
50 {
51     freopen("1057.in","r",stdin);
52     freopen("1057.out","w",stdout);
53     scanf("%d %d",&n,&m);
54     for (int i = 1;i <= n;++i)
55         for (int j = 1;j <= m;++j) scanf("%d",s[i]+j);
56     deal(); work(0); work(1);
57      printf("%d\n%d",ans1,ans2);
58     fclose(stdin); fclose(stdout);
59     return 0;
60 }
View Code

posted @ 2015-02-23 09:10  lmxyy  阅读(...)  评论(... 编辑 收藏