智乃的密码<每日一题>

题目:

题目链接:登录—专业IT笔试面试备考平台_牛客网


思路:

(条件1:字符串按照题目要求分类大于或等于3种)

(条件2:字符串的数量小于或等于R)

(条件3:字符串的数量大于或等于L)

从字符串的第一位开始遍历

找到刚好满足题目所需条件1的位置

然后对其找到它的

左端点(刚好满足条件1和条件3所需的位置)

右端点(满足条件2的最大字符串数量的位置)

答案ans加上

右端点减去左端点(l-r)

加上最短字符串(1)

这就是从第一位到第n位所有数

固定一个字符串能确定的情况

然后依次遍历完所有满足条件的个数

最后得出所有满足条件的答案


代码详解:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,L,R,a[10],num=0;
char str[N];
int t(char c)//对字符类型进行辨别
{
	if('A'<=c&&c<='Z')return 1;
	else if('a'<=c&&c<='z')return 2;
	else if('0'<=c&&c<='9')return 3;
	else return 4;
}
int main()
{
	cin>>n>>L>>R;
	cin>>str+1;
	ll ans=0;
	ll p=0;
	for(int i=1;i<=n;i++)
	{
		while(p<n&&num<3)//找到刚好满足有三个不同类型的字符的字符串 
		{
			int s=t(str[p+1]);
			if(a[s]==0)//
				num++;//统计字符串的字符种类数 
			a[s]++;
			p++;//统计密码的字符串个数 
		}
		if(num>=3)
		{
			int l=max(i+L-1,p);//刚好满足题目条件的位置 
			int r=min(n,i+R-1);//满足条件所能取到的最大的位置 
			ans+=max(0,r-l+1);//r到l区间内能取的值加上自己本身
		}
		int s=t(str[i]);
		a[s]--;//取下一个位置,减去原位置的地方字符类型的数量 
		if(a[s]==0)//如果在这个最短的字符串范围内只有i位置这一个字符串类型 
			num--;//减去最短字符串的总类型 
	}
	cout<<ans;
	return 0;
}

PS:苟利国家生死以,岂能福祸避趋之。--林则徐

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CTGU-Yoghurt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值