代码改变世界

棋盘制作

2019-05-15 21:08  一只弱鸡丶  阅读(244)  评论(0编辑  收藏  举报

传送门:

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 <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define re register
const 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"<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m;j++)
            cout<<lef[i][j]<<" ";
        cout<<endl;
    }
    cout<<"right1"<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m;j++)
            cout<<righ[i][j]<<" ";
        cout<<endl;
    }
    cout<<"up1"<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m;j++)
            cout<<up[i][j]<<" ";
        cout<<endl;
    }*/
    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];
    /*cout<<"left2"<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m;j++)
            cout<<lef[i][j]<<" ";
        cout<<endl;
    }*/
    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];
    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<<i<<" "<<j<<" "<<"1"<<endl;
            if(a*up[i][j]>ans2)
                cout<<i<<" "<<j<<" "<<"2"<<endl;*/
            ans1=max(ans1,b*b);
            ans2=max(ans2,a*up[i][j]);
        }
    printf("%d\n%d",ans1,ans2);
    return 0;
}