题目:
题目链接:登录—专业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:苟利国家生死以,岂能福祸避趋之。--林则徐