codeforces1354B. Ternary String
题目如下
You are given a string 𝑠 such that each its character is either 1, 2, or 3. You have to choose the shortest contiguous substring of 𝑠 such that it contains each of these three characters at least once.
A contiguous substring of string 𝑠 is a string that can be obtained from 𝑠 by removing some (possibly zero) characters from the beginning of 𝑠 and some (possibly zero) characters from the end of 𝑠.
Input
The first line contains one integer 𝑡 (1≤𝑡≤20000) — the number of test cases.
Each test case consists of one line containing the string 𝑠 (1≤|𝑠|≤200000). It is guaranteed that each character of 𝑠 is either 1, 2, or 3.
The sum of lengths of all strings in all test cases does not exceed 200000.
Output
For each test case, print one integer — the length of the shortest contiguous substring of 𝑠 containing all three types of characters at least once. If there is no such substring, print 0 instead.
题目大意
给我们一个又数字‘1’,‘2’和‘3’随机排序构成的串,要求找出其中最短的子串且这三个数字均要存在
解题思路
在串里找目标,我们可以通过滑动窗口算法来实现
滑动窗口算法呢,分为左右两个边界,都从字符串的最左边开始,先从开始的地方向右扩展右边界,左右边界中间夹着的即为窗口,一般窗口里最终包含我们需要的内容,满足一定条件,就收缩左边,这里我们需要满足子串里三个数字均出现,直到收缩完成取到最小的符合要求的子串
点击查看代码
for(int right = 0; right < n; right++){
cnt[s[right]]++; //扩展右边界
while(cnt['1'] && cnt['2'] && cnt['3']){ //满足条件
if(right - left + 1 < res){
res = right - left + 1; //每次窗口合法时,更新最大窗口长度
}
cnt[s[left]]--; //伴随收缩减少各数字的数量
left++; //收缩左边界
}
}
注意,在本题中可能出现runtime error 分配太大导致运行崩溃,所以建议把数组定义放在全局,自动清零,避免溢出;
完整代码
点击查看代码
#include <iostream>
#include <stdio.h>
#include <map>
#include <string.h>
using namespace std;
char s[200005]; //避免溢出
int main() {
int t;
scanf("%d", &t);
while(t--){
scanf("%s",s);
int n = strlen(s);
map<char, int> cnt; //统计子串中1,2,3的数量
int left = 0;
int res = n + 1;
for(int right = 0; right < n; right++){
cnt[s[right]]++; //扩展右边界
while(cnt['1'] && cnt['2'] && cnt['3']){ //满足条件
if(right - left + 1 < res){
res = right - left + 1; //每次窗口合法时,更新最大窗口长度
}
cnt[s[left]]--; //收缩左边界
left++;
}
}
if(res <= n){
printf("%d\n",res);
}else{
printf("0\n");
}
}
return 0;
}

浙公网安备 33010602011771号