A题 CodeForces - 1060C Maximum Subrectangle
题意:输入n,m以及两个长度分别为n和m的数组A和B,这两个数组分别是二维数组C的第一行和第一列,其余元素遵循Ci,j=Ai*Bj。再输入一个整数x。在二维数组C中找内部元素和不大于x的矩形,求矩形的最大面积。
思路:首先搞清楚一个规律:对于任意一个子矩阵(l1…r1)(l2…r2),其内部元素和等于(a[l1]+a[l1+1]+…a[r1])x(b[l2]+b[l2+1]+…+b[r2])。所以需要前缀和处理计算各部分元素和。(ma[i]:表示在数组a中长度为i的子数组元素和最小值)然后用两个数组ma和mb找到子数组元素和最小值,然后枚举两数组长度即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
ll n,m,x,ans,a[2010],b[2010],sa[2010],sb[2010],ma[2010],mb[2010];
int main(){
scanf("%lld %lld",&n,&m);
sa[0]=sb[0]=0;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sa[i]=sa[i-1]+a[i];
}
for(int i=1;i<=m;i++){
scanf("%lld",&b[i]);
sb[i]=sb[i-1]+b[i];
}
memset(ma,inf,sizeof(ma));
memset(mb,inf,sizeof(mb));
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
ma[j-i+1]=min(ma[j-i+1],sa[j]-sa[i-1]);
}
}
for(int i=1;i<=m;i++){
for(int j=i;j<=m;j++){
mb[j-i+1]=min(mb[j-i+1],sb[j]-sb[i-1]);
}
}
scanf("%lld",&x);
ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(ma[i]*mb[j]<=x) ans=max((int)ans,i*j);
}
}
printf("%lld",ans);
}
E题 CodeForces - 122D Lucky Transformation
题意:输入n,k,一长度为n的数字字符串。每次操作从左到右找到第一个"47",判断它的起始下标是奇数还是偶数,如果是奇数替换为"44",偶数替换为"77",最多可以操作k次。输出操作后的字符串。
思路:把"47"换为"44"只会对当前位置之后产生影响,而换为"77"会对当前位置之前产生影响。若遍历到第i位,此时i为偶数,“Si-1,Si,Si+1”=“447”,则这部分会产生"447"->“477”->“447”->…的循环,此时判断剩余操作数奇偶性即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int n,k,len;
char s[100010];
int main(){
scanf("%d %d",&n,&k);
scanf("%s",s);
len=strlen(s);
for(int i=0;i<len-1;i++){
if(k==0) break;
if(s[i]=='4'&&s[i+1]=='7'){
if(i>0&&s[i-1]=='4'){
if(i%2){
if(k%2) s[i]='7';
k=0;continue;
}
}
if(i%2) s[i]='7';
else s[i+1]='4';
k--;
}
}
printf("%s",s);
}