Educational Codeforces Round 87 (Rated for Div. 2) B. Ternary String (思维,贪心)

题目传送
题意:
给你一个只由1 2 3这三个数字组成的字符串,现在要求你求出其中包含1 2 3的子串(这个子串指的是连续的字符串片段),问:这个满足条件的子字符串最短的长度为多少,如果不存在输出0.

思路:
很明显,要求最短,那么在这个字符串中,我们先一个for从第一个位置开始找,然后我们取每一种数的最大的位置(可以使得,存在这三种数的字符串压缩到最短),当三个数在遍历的过程中,都存在了(现在寻找的字符串已经满足了存在1 2 3),那么更新最小值。

说得糊里糊涂的。。。。。看代码,很容易懂,没多少行

AC代码

#include 
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
const int N = 5e5 + 5;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const unsigned long long mod = 998244353;
const double II = 3.1415926535;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        cin >> s;
        int vis1 = -1,vis2 = -1,vis3 = -1,Min = INF;
        //-1代表暂时没有存在
        for(int i = 0;i < s.size();i++)
        {
            if(s[i] == '1') vis1 = max(vis1,i);
            if(s[i] == '2') vis2 = max(vis2,i);
            if(s[i] == '3') vis3 = max(vis3,i);
            //取这个数最右边的位置,可以使得前面重复删去
            //如:11111223,那么我们取到的1把左边无用的去掉了
            if(vis1 != -1 && vis2 != -1 && vis3 != -1)
            {
                int a = max(vis1,max(vis2,vis3)),b = min(vis1,min(vis2,vis3));//这个是为了算子字符串的长度
                Min = min(Min,a-b+1);//更新最小值
            }
        }
        if(Min == INF) cout << 0 << endl;//不存在
        else cout << Min << endl;
    }
}

你可能感兴趣的:(codeforces,贪心,思维)