left[i][j]计算这个位置这个点能跑到的最左边的位置
right[i][j]计算这个位置这个点能跑到的最右边的位置
up[i][j]计算这个位置这个点能向上跑的最上的位置
那么很明显对每个位置长就是right[i][j]-left[i][j]+1 宽就是min(u[i][j],right[i][j]-left[i][j]+1)
初始化时维护自己当前位置就行了
left递推式为
for(re int i=1;i<=n;i++)
for(re int j=2;j<=m;j++) if(res[i][j]!=res[i][j-1]) lef[i][j]=lef[i][j-1];right递推式为
for(re int i=1;i<=n;i++)
for(re int j=m-1;j>0;j--) if(res[i][j]!=res[i][j+1]) righ[i][j]=righ[i][j+1];那么问题就得到解决了
#include#include #include #include using namespace std;#define ll long long#define re registerconst int maxn=2001;void read(int &a){ a=0; int d=1; char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d;}int res[maxn][maxn],lef[maxn][maxn],righ[maxn][maxn],up[maxn][maxn];int n,m,ans1,ans2;int main(){ read(n); read(m); for(re int i=1;i<=n;i++) for(re int j=1;j<=m;j++) { read(res[i][j]); lef[i][j]=righ[i][j]=j; up[i][j]=1; } /*cout<<"left1"< 0;j--) if(res[i][j]!=res[i][j+1]) righ[i][j]=righ[i][j+1]; for(re int i=1;i<=n;i++) for(re int j=1;j<=m;j++) { if(i>1&&res[i][j]!=res[i-1][j]) { lef[i][j]=max(lef[i][j],lef[i-1][j]); righ[i][j]=min(righ[i][j],righ[i-1][j]); up[i][j]=up[i-1][j]+1; } int a=righ[i][j]-lef[i][j]+1; int b=min(a,up[i][j]); /*if(b*b>ans1) cout< <<" "< <<" "<<"1"< ans2) cout< <<" "< <<" "<<"2"<