锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

第一届程序设计竞赛题解(J题)

时间:2022-09-04 15:30:00 继电器aqw215a

J.学长陈梓豪的密码

题目描述:

一天,陈梓豪学长去注册账号。
陈梓豪学长发现,该网站的密码必须符合以下要求三个条件
至少应包括密码大写英文字母英文小写字母数字特殊符号这四种字符中有三种。
密码长度不小于 L 而且字符不多 R 个字符。
密码是只包含英文字母、数字和特殊符号的字符串。
特殊字符是指非大小写字母、数字、空格回车等不可见字符的可见字符,包括但不限于 “!@#^()_ *” 。

现在,陈末给了陈梓豪一个长度 N 的字符串 S ,学长陈梓豪想知道 S 串中有多少个子串是一个符合条件的密码。
请帮助陈梓豪统计合格的密码数量。

子串是指字符串中某一段的连续范围,如字符串 “aqwerdf” 来说,“aqw”, “qwe” 都是它的子串,而且 “aqr” 不是它的子串。

输入描述:

第一行输入三个正整数 N, L, R (1 <= N <= 105), (1 <= L <= R <= N),表示字符串的长度和合法字符的长度限制 。
第二行输入一个长度 N 的字符串 S 。
保证字符串只包括英文字母、数字和特殊符号。

输出描述:

一个整数表示有多少个子串是合法的密码

示例:

输入:
6 2 6
abcD2!
输出:
7
说明:
abcD2
bcD2
cD2
D2!
abcD2!
bcD2!
cD2!

思路:
先用一个 flag[5] 数组判断字符类型,flag[1] ~ flag[4] 表示四个字符,flag[0] 表示现有的字符类型。
要求合格的子串密码,我们可以使用快速和慢指针一步一步地通过字符串,每次添加一个,最终输出结果。

AC代码如下:

#include  using namespace std; const int N = 1e5   5;  int n, L, R; int flag[5]; char s[N];  ///判断字符的函数 int P(int x) { 
             if (s[x] >= 'A' && s[x] <= 'Z')         return 1;     if (s[x] >= 'a' && s[x] <= 'z')         return 2;     if (s[x] >= '0' && s[x] <= '9')         return 3;     ///其他字符返回4     return 4;
}

int main()
{ 
        
    //初始化
    scanf("%d %d %d\n", &n, &L, &R);
    scanf("%s", s + 1);

	//快慢指针
    int l = 1, r = 0;
    int ans = 0;
    while (l <= n){ 
        
        while (r - l + 1 <= R && r < n){ 
        
        	//右指针先右移一位后,判断是哪种字符
            int p = P(r++);

			//统计字符种类,若没有该字符,则加一,标记为已存在
            if (flag[p] == 0)
                flag[0]++;

			//该字符数量加一
            flag[p]++;

			//若子串中字符种类有三种及以上,且符合合法字符的长度限制
            if (flag[0] >= 3 && r - l + 1 >= L){ 
        
                ans += min(n - r + 1, R - (r - l + 1) + 1);
                break;
            }
        }

		//右移左指针
        int p = P(l++);

		//若该种字符已存在,右移,字符种类减一
        if (flag[p] == 1)
            flag[0]--;

		//字符数量减一
        flag[p]--;

        if (flag[0] >= 3 && r - l + 1 >= L)
            ans += min(n - r + 1, R - L + 1);
    }

    printf("%d\n", ans);

    return 0;
}

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章