资讯详情

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

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 <bits/stdc .h> 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;
}

标签: 继电器aqw215a

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

锐单商城 - 一站式电子元器件采购平台