题目链接
给定一个矩阵,最多进行 次操作,每次可以把 B
改成 G
,G
改成 B
,P
不能改,问最后能得到的最大的颜色相同的子矩阵。
由于 ,所以应该是一个 的做法。
我们枚举一个矩阵的最上行 ,最下行 ,最左列和最右列的指针分别为 ,这是就确定了一个矩阵,由于具有单调性,所以我们可以每次判断如果能够在 次操作内将其改成相同矩阵(前缀和预处理),就可以考虑将矩阵加大即 ,否则 。注意如果当前只有一列,且不合法,并不代表后面也不合法,需要 都向后推一列。
注意对于每一个 都有最大的 ,所以开数组存下这个 ,然后你需要记录最大的矩阵面积。
有个坑点,要注意紫名矩阵也算,方法一样。
细节较多,码风较丑,仅供参考。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void read(int &x)
{
char ch=getchar();
int r=0,w=1;
while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar();
while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar();
x=r*w;
}
const int N=507;
char c[N][N];
int sumb[N][N],sumg[N][N],l[N][N],r[N][N],ans[N][N],anss[N][N],ls[N][N],rs[N][N],ss[N][N];
bool ok=0;
int queryb(int a,int b,int c,int d)
{
return sumb[c][d]-sumb[c][b-1]-sumb[a-1][d]+sumb[a-1][b-1];
}
int queryg(int a,int b,int c,int d)
{
return sumg[c][d]-sumg[c][b-1]-sumg[a-1][d]+sumg[a-1][b-1];
}
main()
{
int n,m,k;
read(n);read(m);read(k);
for(int i=1;i<=n;i++)
scanf("%s",c[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
sumb[i][j]=sumb[i-1][j]+sumb[i][j-1]-sumb[i-1][j-1]+(c[i][j]=='B');
sumg[i][j]=sumg[i-1][j]+sumg[i][j-1]-sumg[i-1][j-1]+(c[i][j]=='G');
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
int L=1,R=1;
while(L<=R&&R<=m)
{
int s=ans[i][j];
if((R-L+1)*(j-i+1)-queryb(i,L,j,R)-queryg(i,L,j,R)!=0)
{
L++;
if(L>R&&R<m)R++;
continue;
}
if(min(queryb(i,L,j,R),queryg(i,L,j,R))<=k)
{
ans[i][j]=max(ans[i][j],(R-L+1)*(j-i+1));
if(ans[i][j]>s)l[i][j]=L,r[i][j]=R;R++;
}
else L++;
if(L>R&&R<m)R++;
}
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
int L=1,R=1;
while(L<=R&&R<=m)
{
int s=anss[i][j];
if(queryb(i,L,j,R)+queryg(i,L,j,R)==0)
{
anss[i][j]=max(anss[i][j],(R-L+1)*(j-i+1));
if(anss[i][j]>s)ls[i][j]=L,rs[i][j]=R;
R++;
}
else
{
L++;
if(L>R&&R<m)R++;
continue;
}if(L>R&&R<m)R++;
}
}
int sb=0,ansi,ansj;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
if(sb<ans[i][j])
{
ok=0;
sb=ans[i][j];
ansi=i,ansj=j;
}
if(sb<anss[i][j])
{
sb=anss[i][j];
ok=1;
}
}
cout<<sb<<endl;
if(ok)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i>=ansi&&i<=ansj&&j>=ls[ansi][ansj]&&j<=rs[ansi][ansj])
cout<<"P";
else cout<<c[i][j];
}
cout<<endl;
}
return 0;
}
if(queryb(ansi,l[ansi][ansj],ansj,r[ansi][ansj])<=k)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i>=ansi&&i<=ansj&&j>=l[ansi][ansj]&&j<=r[ansi][ansj])
cout<<"G";
else cout<<c[i][j];
}
cout<<endl;
}
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i>=ansi&&i<=ansj&&j>=l[ansi][ansj]&&j<=r[ansi][ansj])
cout<<"B";
else cout<<c[i][j];
}
cout<<endl;
}
}
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】