Codeforces Round #634 (Div. 3) 比赛人数11922 慢慢的对Div. 3难度有了些感觉
[codeforces 1335E1] Three Blocks Palindrome (easy version) 分成左中右3个区间+前缀和
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1335/problem/E1
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
E1 - Three Blocks Palindrome (easy version) | GNU C++17 | Accepted | 109 ms | 200 KB |
思路如下
1.将数组分成[1,i-1],[i,j],[j+1,n]三个区间
找雷同数字数量,全部用前缀和维护。
2.在[1,i-1]区间内找出雷同数字的数量l,[j+1,n]区间内找出与左区间同一雷同数字的数量r,取最小值l=min(l,r)
遍历26个数字,找上述l的最大值
3.在[i,j]区间,找雷同字母数量mid
遍历26个数字,找上述mid的最大值
4.答案就是在mid+l*2中找最大值(l*2代表左右区间雷同字母数量)
AC代码如下
#include <cstdio>
#include <algorithm>
#define maxn 2010
using namespace std;
int a[maxn],sum[30][maxn];
int main(){
int t,n,i,j,l,r,mx,k,mid,ans,b;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=26;i++)
for(j=1;j<=n;j++)
sum[i][j]=0;//前缀和初始化
for(i=1;i<=n;i++){
for(j=1;j<=26;j++)
sum[j][i]=sum[j][i-1];
sum[a[i]][i]+=1;//前缀和计算
}
ans=0;
for(i=1;i<=n;i++)
for(j=i;i<=j&&j<=n;j++){
b=0;mid=0;
for(k=1;k<=26;k++){//找出雷同数字,左,右区间数量
l=sum[k][i-1]-sum[k][0],r=sum[k][n]-sum[k][j];
if(l>r)l=r;
b=max(b,l);
}
for(k=1;k<=26;k++)//找出雷同数字,中间区间数量
mid=max(mid,sum[k][j]-sum[k][i-1]);
ans=max(ans,mid+b*2);//将左,中,右区间拼接
}
printf("%d\n",ans);
}
return 0;
}