luogu1169 [ZJOI2007]棋盘制作

悬线法

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, m, h[2005][2005], l[2005][2005], r[2005][2005], uu, iii=0, jjj=0;
bool a[2005][2005];
void rn(int &x){
	char ch=getchar();
	x = 0;
	while(ch<'0' || ch>'9')	ch = getchar();
	while(ch>='0' && ch<='9'){
		x = x * 10 + ch - '0';
		ch = getchar();
	}
}
void work(){
	int ans=0, maxn=0;
	memset(h, 0, sizeof(h));
	for(int i=1; i<=n; i++){
		int x=1;
		for(int j=1; j<=m; j++)
			if(a[i][j])	l[i][j] = x;
			else	l[i][j] = 1, x = j + 1;
		x = m;
		for(int j=m; j>=1; j--)
			if(a[i][j])	r[i][j] = x;
			else	r[i][j] = m, x = j - 1;
	}
	for(int i=1; i<=m; i++)	l[0][i] = 1, r[0][i] = m;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(a[i][j]){
				h[i][j] = h[i-1][j] + 1;
				l[i][j] = max(l[i][j], l[i-1][j]);
				r[i][j] = min(r[i][j], r[i-1][j]);
				ans = max(ans, (r[i][j]-l[i][j]+1)*h[i][j]);
				maxn = max(maxn, min(h[i][j], (r[i][j]-l[i][j]+1)));
			}
	iii = max(iii, maxn*maxn);
	jjj = max(jjj, ans);
}
int main(){
	cin>>n>>m;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++){
			rn(uu);
			a[i][j] = uu;
			if((i+j)%2==0)	a[i][j] ^= 1;
		}
	work();
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			a[i][j] ^= 1;
	work();
	cout<<iii<<endl<<jjj<<endl;
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8034521.html