您的位置:首页 > 其它

bzoj 1057: [ZJOI2007]棋盘制作

2014-01-22 10:45 246 查看
首先是对于图上所有的棋盘一定属于以下两种类型:

1.黑格行列奇偶性相同,白格不同

2.白格行列奇偶性相同,黑格不同

那么在输入的时候属于第一种情况的赋1,属于第二种情况的赋0

统计最大的1或0矩形和正方形就可以啦。

统计矩形和玉蟾宫是一样的做法,单调栈嘛。

#include <cstdio>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 2008

int ans1,ans2,n,m,f

,s
,w
,top;
bool map

;

void build()
{
scanf("%d%d",&n,&m);
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
{
int a; scanf("%d",&a);
if ((i & 1) == (j & 1) && a || (i & 1) != (j & 1) && !a) map[i][j] = 1;//& 优先级低于 ==!!
else map[i][j] = 0;
}
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
if (map[i][j]) f[i][j] = f[i][j-1] + 1;
else f[i][j] = 0;
}

void rebuild()
{
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
//            map[i][j] = ~map[i][j]; 不能按位取反!!因为第一位之后的也会取反!!
map[i][j] = !map[i][j];
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
if (map[i][j]) f[i][j] = f[i][j-1] + 1;
else f[i][j] = 0;
}

inline int sqr(int a)
{return (a*a);}

void work()
{
for (int j = 1;j <= m;j++)
{
top = 0;
for (int i = 1;i <= n + 1;i++)
{
int minw = i;
while (top && s[top] >= f[i][j])
{
ans1 = max(ans1,s[top] * (i - w[top]));
ans2 = max(ans2,sqr(min(s[top],i-w[top])));
minw = w[top];
top--;
}
s[++top] = f[i][j]; w[top] = minw;
}
}
}

void makeline()
{for (int i = 1;i <= m;i++) printf("--");printf("\n");}

void debug()
{
makeline();
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= m;j++) printf("%d ",map[i][j]);
printf("\n");
}
makeline();
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= m;j++) printf("%d ",f[i][j]);
printf("\n");
}
}

int main()
{
//    freopen("input.txt","r",stdin);
build();
//    debug();
work();
rebuild();
//    debug();
work();
printf("%d\n%d\n",ans2,ans1);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: