AcWing 4077.K显性字符

给定一个由小写字母构成的字符串 s
字符 c称为字符串 s 的 k 显性字符,当且仅当字符串 s 的所有长度不小于 k 的子串都包含字符 c
对于给定的字符串 s,请你找到一个最小的 k,使得 s 中至少存在一个 k显性字符。

输入格式

一个由小写字母构成的字符串 s

输出格式

一个整数,表示 k的最小可能值。

数据范围
前 6个测试点满足 1≤|s|≤10。
所有测试点满足 1≤|s|≤105

输入样例1:

abacaba

输出样例1:

2

输入样例2:

zzzzz

输出样例2:

1

输入样例3:

abcde

输出样例3:

3

  • 本题思路:
    要在字符串 s 中寻找长度不小于 k 的子串都包含同一字符,此题中字母都是小写字母,一共26个,可以用二维数组来分别记录某一字母,是第几次在s串中出现和其所在位置(如:dis[第几个字母][第几次出现]=所在位置)。这样一来我们就可以算相同字母之间间隔,这里的间隔取最大值就是该字母如果要作为字符c时k至少要为多少。再在二十六个字母各自最大间隔中取最小的即为最终的结果。此处注意:字母第一次出现距离字符串头,和字母最后一次出现距离字符串尾的长度也需要算在其中。

  • 编写时遇到的问题,像dis这样的二维数组开的很大时就要注意了
    函数内申请的变量,数组,是在栈(stack)中申请的一段连续的空间。栈的默认大小为2M或1M,开的比较小。
    全局变量,全局数组,静态数组(static)则是开在全局区(静态区)(static)。大小为2G,所以能够开的很大。
    由此可见在函数中开时不能开太大,就如同我这里定义的 dis[26][100000];如果是放在main函数中时会造成程序崩溃。

#include<bits/stdc++.h>

using namespace std;
int times[100000];
int dis[26][100000];
int main()
{
    string s;
    cin>>s;
    int m= s.size();
    int n;//表示第几个字符
    for(int i=0; i<m; i++)
    {
        n=s[i]-'a';///表示第几个字符
        times[n]++;
        dis[n][times[n]]=i;///所在位置
    }
    int ans =2e9;
    for(int i=0; i<26; i++)
    {
        int topdis=dis[i][1]+1;///第一次出现距离开头的距离;注意是要+1
        for(int j=1; j<times[i]; j++)
        {

            ///求相同字母每次相邻间隔出现的最大距离
            topdis =max(topdis,dis[i][j+1]-dis[i][j]);
        }
        //cout<<m-dis[i][times[i]]<<"*"<<endl;
        topdis=max(topdis,m-dis[i][times[i]]);//最后一个到结尾的长度
        ///不同字母的最大间隔中找最小的间隔
        ans = min(ans,topdis);

    }
    printf("%d\n",ans);
    return 0;
}

上一篇:【题解】Luogu P5122 Fine Dining G


下一篇:salt-api