蓝桥杯字串简写(二分)
输入![](https://i-blog.csdnimg.cn/direct/58cd25ca75644d0eba53c66c61dfb67d.png)
4
abababdb a b
输出
6
思路:
如果暴力,o(n**2),超时,想到可以先与处理一下,记录c1出现的位置,再根据c2的位置用二分法看前面有多少个符合条件的c1。
why二分:
代码:一些细节注意点在注释上写了,注意用vector.size()时,初始化vector<> v(N),不要写N,不要规定范围(因为这个找了半天错误,服了),还有,v.size()返回的是无符号整型,如果v.size()-x,x>1的话,一定要注意不能为负,或者强制类型转换也可以,(int)v.size()-x;
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+10;
int ans=0;
vector<int> a;
signed main()
{
int k;
cin>>k;
string s;
cin>>s;
char c1,c2;
cin>>c1>>c2;
for(int i=0;i<s.size();i++)
{
if(s[i]==c1)
a.push_back(i);
if(s[i]==c2)
{
if(a.empty()||i-k+1<0) continue;
int l=0,r=a.size()-1;//在前面的c1中寻找
cout<<a.size()<<endl;;
while(l<r)
{
int mid=l+r+1>>1;//临界判断一下
if(a[mid]<=i-k+1) l=mid;
else r=mid-1;
cout<<l<<" "<<r<<endl;
}
if(a[l]<=i-k+1) //一定要判断,因为i-k+1<0的条件筛选只是最初步的,如果i-(第一个c1出现的位置)+1<0的条件,那可以不用这个
ans+=(l+1);
}
}
cout<<ans<<endl;
}