1057: [ZJOI2007]棋盘制作

醉了。。。。。。。。

题目说一个答案占一行,结果我两个答案输出到同一行了TAT。

WA了三次竟然没发现,蠢哭了。

极大化思想的运用。悬垂线法。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int read(){
	char ch;int x=0;
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
int mat[2005][2005],up[2][2005],l[2][2005],r[2][2005];
int ans1,ans2;
int main(){
	int n,m;n=read();m=read();
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)mat[i][j]=read();
	int now=0,last=1;
	for(int i=1;i<=n;i++){
		int lo=1,ro=m;
		now^=1;last^=1;
		for(int j=1;j<=m;j++){
			if(mat[i][j]==mat[i][j-1])lo=j;
			if(mat[i][j]==mat[i-1][j]){
				up[now][j]=1;
				l[now][j]=lo;
			}else{
				up[now][j]=up[last][j]+1;
				l[now][j]=max(l[last][j],lo);
			}
		}
		for(int j=m;j>=1;j--){
			if(mat[i][j]==mat[i][j+1])ro=j;
			if(mat[i][j]==mat[i-1][j]||i==1)r[now][j]=ro;
			else r[now][j]=min(r[last][j],ro);
			int tmp=min(up[now][j],r[now][j]-l[now][j]+1);
			ans1=max(ans1,tmp*tmp);ans2=max(ans2,up[now][j]*(r[now][j]-l[now][j]+1));
		}
	}
	printf("%d\n%d",ans1,ans2);
	return 0;
}


你可能感兴趣的:(1057: [ZJOI2007]棋盘制作)