题解 CF1354B Ternary String
Posted werner-yin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 CF1354B Ternary String相关的知识,希望对你有一定的参考价值。
题意
给出一个字符串,只包含 ({1,2}) 或 ({3}) 。从中找出一个长度最短的子串,要求至少包含 ({1,2,3}) 各一次,并输出其长度。
输入格式
本题有多组测试数据
第一行一个整数 (t) ,表示数据组数
接下来 ({t}) 行,每行一个字符串 (s) ,它的每个字符只可能是 (1,2) 或 (3) 。({s}) 的长度不超过(200000)。
输出格式
对于每组数据,输出一行一个整数,表示最短的符合要求的子串的长度。如果不存在,输出 (0) 。
说明与提示
$ 1 le t le20000$,
$1 le |s| le 200000 $
Solution
我们可以开一个数组 $a $ ,其中 (a_i) 表示 i 上次出现的位置($ 1le i le 3$ ),初始时,(a_i=-1)。
然后线性扫过去,不断更新 (a),当停留在第 $ k $位时, a[ s[k]-‘0‘ ]= k 。 显然,以第 (k) 位结尾的符合要求的子串长度为 k-min(a[1],a[2],a[3])+1 。此时我们可以更新 (ans) 。
代码 ↓
注意多测
#include<bits/stdc++.h>
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;
const int MAXN=200010;
int t,a[5],ans=MAXN;
int main (){
scanf("%d",&t);
while(t--){
string s;
cin>>s;
a[1]=-1;a[2]=-1;a[3]=-1;ans=MAXN;
int ls=s.length();
for(int i=0;i<ls;i++){
a[s[i]-‘0‘]=i;
int minn=MAXN;
for(int j=1;j<=3;j++){
minn=min(minn,a[j]);
}
if(minn==-1)continue;
ans=min(ans,i-minn+1);
if(ans==3)break;
}
if(ans==MAXN)printf("0
");
else printf("%d
",ans);
}
return 0;
}
本蒟蒻第一次写题解,巨佬轻喷
以上是关于题解 CF1354B Ternary String的主要内容,如果未能解决你的问题,请参考以下文章
[CF1009B]Minimum Ternary String(思维)
CF1009B Minimum Ternary String 思维
Balanced Ternary String CodeForces - 1102D (贪心+思维)
B. Minimum Ternary String (这个B有点狠)