0
点赞
收藏
分享

微信扫一扫

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

钵仔糕的波波仔 2022-04-24 阅读 81
c++算法

J.陈梓豪学长的密码

题目描述:

输入描述:

输出描述:

示例:

思路:
首先使用一个 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;
}

举报

相关推荐

0 条评论